题目描述

The numberic keypad on your mobile phone looks like below:
123
456
789
 0
 suppose you are holding your mobile phone with single hand. Your thumb
points at digit 1. Each time you can 1)press the digit your thumb
pointing at.2)moveyour thumb right,3)move your thumb down. Moving your
thumb left or up is not allowed.
 By using the numeric keypad under above constrains, you can produce
some numbers like 177 or 480 while producing other numbers like 590 or
52 is impossible.
 Given a number K, find out the maximum number less than or equal to K
that can be produced.

输入描述:
the first line contains an integer T, the number of testcases.
Each testcase occupies a single line with an integer K. For 50%of the data ,1<=K<=999.
For 100% of the data, 1<=K<=10^500,t<=20.
输出描述:
for each testcase output one line, the maximum number less than or equal to the corresponding K that can be produced.
输入例子:
3
25
83
131
输出例子:
25
80
129

剑指offer公司真题部分,微软的题目。
根据题意,可以知道的是,按下某个键后,这个键左方及上方的键不能再用了。例如按下了[5]:

所以我们可以得到一张表,以表示按下某个键后还剩下的合法按键:
 
一个数组表示key,也就是当前被查的字符。
一个数组last表示,当前被查字符的可用数字的个数。例如1是9,0是0,9是0。
 
例如来一个131.
把1输入进去。
从3开始查。need=3;
会有以下三种情况:
  找到need。。如果找到,那么查找下一个字符,也就是1.
  找不到need。。我试着找第一个小于need的数。那么后面的所以数位则填充当前最大的合法值,结束,返回;
  连小于need的数我都找不到。。就像这个例子,我在key=3的时候,找need=1。我根本找不到,这个时候,需要回到key=1的时候(需要pop,遇到字符串为空的情况需要特殊处理),找1的可用数组里,比need稍微小一点的(不能直接找need-1,因为need-1可能不在可用数组里。),那么后面的所以数位则填充当前最大的合法值,结束,返回。
 

#include <iostream>
#include <vector>
#include <string>
#include <queue>
using namespace std;
int pad[][] = {
{ },
{ ,,,,,,,,, },
{ ,,,,,, },
{ ,, },
{ ,,,,,, },
{ ,,,, },
{ , },
{ ,,, },
{ ,, },
{ } };
int last[] = { ,,,,,,,,, }; string maxnum(string& s1) {
string s2;
s2.push_back(s1[]);
int len = s1.length();
for (int i = ; i < len; ) {
int need = s1[i] - '';
int key = s2.back() - '';
int j = ;
for (j = last[key]; j >= ; j--)
{
if (pad[key][j] == need) {
i++;
s2.push_back(pad[key][j] + '');
break;
}
} if (j < ) {
for (j = last[key]; j >= ; j--)
{
if (pad[key][j] < need) {
s2.push_back(pad[key][j] + '');
key = s2.back() - '';
for (int j = s2.size(); j < len; j++)
s2.push_back(pad[key][last[key]] + '');
return s2;
}
}
} if (j < ) {
need = key;
s2.pop_back();
if (s2.size() == ) {
s2.push_back(need - + '');
key = s2.back() - '';
for (int j = s2.size(); j < len; j++)
s2.push_back(pad[key][last[key]] + '');
return s2;
} key = s2.back()-'';
for (j = last[key]; j >= ; j--)
{
if (pad[key][j] < need) {
s2.push_back(pad[key][j] + '');
key = s2.back() - '';
for (int j = s2.size(); j < len; j++)
s2.push_back(pad[key][last[key]]+'');
return s2;
}
}
} }
return s2;
} int main() {
int num;
cin >> num;
vector<string> vec(num,"");
for (int i = ; i < num; i++)
cin >> vec[i];
for (int i = ; i < num; i++)
cout << maxnum(vec[i]) << endl;
return ;
}
												

【每天一道算法题】Numeric Keypad的更多相关文章

  1. 每天一道算法题(4)——O(1)时间内删除链表节点

    1.思路 假设链表......---A--B--C--D....,要删除B.一般的做法是遍历链表并记录前驱节点,修改指针,时间为O(n).删除节点的实质为更改后驱指针指向.这里,复制C的内容至B(此时 ...

  2. 从一道算法题实现一个文本diff小工具

    众所周知,很多社区都是有内容审核机制的,除了第一次发布,后续的修改也需要审核,最粗暴的方式当然是从头再看一遍,但是编辑肯定想弄死你,显然这样效率比较低,比如就改了一个错别字,再看几遍可能也看不出来,所 ...

  3. 【每天一道算法题】时间复杂度为O(n)的排序

    有1,2,……一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度为O(1),使用交换,而且一次只能交换两个数. 这个是以前看到的算法题,题目不难.但是要求比较多,排序算法中,时间 ...

  4. 提前批笔试一道算法题的Java实现

    题目描述 这是2021广联达校招提前批笔试算法题之一. 我们希望一个序列中的元素是各不相同的,但是理想和显示往往是有差距的.现在给出一个序列A,其中难免有相同的元素,现在提供了一种变化方式,使得经过若 ...

  5. 每天一道算法题-leetcode136-只出现一次的数字

    前言 打卡第一天 2019.10.26日打卡 算法,即解决问题的方法.同一个问题,使用不同的算法,虽然得到的结果相同,但是耗费的时间和资源是不同的.这就需要我们学习算法,找出哪个算法更好. 大家都知道 ...

  6. 一道算法题加深我对C++中map函数的理解

    一.一道题目引发我对map函数的考量 首先是题目大意:有n个银行,a[i]表示这个人在第i个银行有a[i]块钱(可以是负数),所有银行的钱加起来正好是0.每次只能在相邻的银行之间转账,问最少要转多少次 ...

  7. 每天一道算法题(14)——N个降序数组,找到最大的K个数

     题目: 假定有20个有序数组,每个数组有500个数字,降序排列,数字类型32位uint数值,现在需要取出这10000个数字中最大的500个. 思路 (1).建立大顶堆,维度为数组的个数,这里为20( ...

  8. 认真对待每一道算法题 之 两个排序好的数组寻找的第k个大的数

    转载博客:http://www.cnblogs.com/buptLizer/archive/2012/03/31/2427579.html 题目意思:给出两个排好序的数组 ,不妨设为a,b都按升序排列 ...

  9. 《github一天一道算法题》:分治法求数组最大连续子序列和

    看书.思考.写代码. /*************************************** * copyright@hustyangju * blog: http://blog.csdn. ...

随机推荐

  1. Oracle数据库中的重要对象

    数据库中的重要对象:表.视图.序列.函数.存储过程.索引.同义词1.表:用PL/SQL Developer 软件打开 Scott的DEPT表查看SQL,可以看见DEPT表创建的脚本-- Create ...

  2. redis源码笔记(一) —— 从redis的启动到command的分发

    本作品采用知识共享署名 4.0 国际许可协议进行许可.转载联系作者并保留声明头部与原文链接https://luzeshu.com/blog/redis1 本博客同步在http://www.cnblog ...

  3. [基础架构]PeopleSoft工作原理(从浏览器发送请求开始)

    PeopleSoft体系结构是由几大组成部分构成,之前文章已经详细讲过,了解这几大组成部分是怎么协同工作的更为重要.在本文中将帮助您了解PeopleSoft的工作原理以及用户发送的请求是如何被解析以及 ...

  4. Java用Cookie简单限制点赞次数

    楼主最近在搞一个当下比较流行的点赞功能,这个功能也是让程序员又爱又恨啊 说起爱,点赞是个社会化的动作,全民都在为美好的事情,行为,动作,点赞. 说起恨,你很难在用户没有登录的情况下限制恶意点赞的机器人 ...

  5. Intellij Idea配置说明(从Eclipse转Idea)

      1.idea的字体大小设置 字体大小设置的方法: 进入Settings>>Editor>>Colors&Fonts>>Font,改变Size大小. 2. ...

  6. 第一篇:webservice初探

    接触webservice也有一段时间了,为了查缺补漏,把知识点系统化,准备写几篇博文梳理下webservice的知识点,这是第一篇,对webservice进行大致的介绍. 1.什么是webservic ...

  7. 文件的默认权限UMASK

    当进入Linux系统后新创建的文件或者文件夹总是会有一个默认的权限,那么这个权限是如何设置的呢? umask就是设置文件与目录的默认权限 1. 查看umask 直接查看, [root@centos6 ...

  8. serv-u 多域配置

    serv-U后,默认情况下可以通过在浏览器中输入http://IP 的方式登录到serv-u ftp 服务器控制台,也就是说serv-u在80端口监听,这样,如果想配置多个域或者是想在自己电脑上安装A ...

  9. [补] 如何在windows下用IDA优雅调试ELF

    在windows下如何用IDA优雅调试ELF brief: 构建一个IDA-linux_server-docker镜像,优雅地IDA远程调试 使用传统虚拟机来运行一个linux程序就得跑一个完整的li ...

  10. (转)每天一个linux命令(50):crontab命令

    场景:在学习Linux环境下自动部署项目时候,可以通过crontab命令设定定时任务,实现服务端项目的自动部署! 前一天学习了 at 命令是针对仅运行一次的任务,循环运行的例行性计划任务,linux系 ...