Numeric Keypad:多思考,别蛮力!

来源:互联网 发布:java 线程安全的集合 编辑:程序博客网 时间:2024/06/05 05:33

题目描述

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.

输入例子:
32583131

输出例子:
2580

129

思路:

1.技巧一:想要取得一个大整数的各个位,不要一根筋想着%10,/10,这样的操作很麻烦。可以,考虑,to_string()函数,把一个数变成字符串可以很快的提取它的各个位。

2.我起初很傻的这样,如果一个大数N不合法,则从比N小的地方开始往下找,真是蠢至极。。。。你想想,如果一个数字是9111111111111,你后面再怎么找,都是不合法的,因为第一个数是9。

3.思路如下:在代码注释中可见。

1.在找小于它的最大值的时候,肯定是往‘9’上面靠拢,这点意识要有!

2.每改变一个数字,就把后面的所有位都置为9,显然是最大的。

3.每修改完一个数字,记得再次往前回溯比较。

当前数字>1,记得回溯比较,显然还是合法的。

当前数字=0,前面数字要借位,前面数字-1;但是,前面数字修改之后一定不能违反合法性。

#include <iostream>#include <string>using namespace std;void locate(int digit,int&x,int&y){    digit=digit?--digit:10;    x=digit/3;    y=digit%3;}bool canReach(int x,int y){      int x0,y0,x1,y1;      locate(x,x0,y0);      locate(y,x1,y1);      return x0<=x1&&y0<=y1;}int main(){       int n;        for (cin>>n; n--; )    {        string curstr;        cin>>curstr;        int i=1;        int len=curstr.size();        while(i<len){            int curNum=curstr[i]-'0';            int preNum=curstr[i-1]-'0';            if(!canReach(preNum,curNum)){                if(curNum>=1){                    curstr[i]--;//修改完当前数字后,要考虑到有没有影响到前一位到当前位的合法性。                    //显然此处还是合法的,所以不用i--;                    for (int j = i+1; j < len; ++j) curstr[j]='9';                }                else{                    curstr[i-1]--;                    for (int j = i; j < len; ++j) curstr[j]='9';                    i--;//这一步相当重要,比如测试996,你试试看如果没有这一步会怎么样。                    //当996-->990-->989时,前一位被修改了,由9变为8,所以还是可能引起非法。所以要往前回溯一个。                }            }else                ++i;        }        cout<<curstr<<endl;    }    return 0;}



0 0
原创粉丝点击