浙大pat | 浙大pat 牛客网PAT顶级(Top Level)练习题 1002

 1002

Numeric Keypad

796

5608

14%

The numberic keypad on your mobile phone looks like below:

 123

 456

 789

  0

  suppose you areholding your mobile phone with single hand. Your thumb

points at digit 1. Each time you can 1)press the digit yourthumb

pointing at.2)moveyour thumb right,3)move your thumb down.Moving your

thumb left or up is not allowed.

  By using thenumeric keypad under above constrains, you can produce

some numbers like 177 or 480 while producing other numbers like590 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 thanor equal to the corresponding K that can be produced.



输入例子:

3
25
83
131



输出例子:

25
80
129

这题虽然说一次就ac了,但是花费了一个多小时,要是考试早就GG了

首先打个表,theForm[i][j]表示取到i之后下一步能否取到j,然后遍历K,K用字符串表示,因为可能出现极大的数。

首先去掉K首部的0,因为K首部有0的话算法会失败,

然后尽量多的取K前面的数,当出现第一个不能取到的数K[i]的时候,假如这个数字比K[i-1]大,那么取比K[i]小的最大的一个数字,假如这个数是0,那么后面都是0,假如这个数字是非0,那么后面都是9

假如K[i]比K[i-1]小,假如K[i-1]是3,6,9(因为3,6,9之后的数字不能往小取),那么向前查找,找到第一个不是3,6,9的数字,取小,假如这个数字是0,那么后面都是0,假如这个数字不是0,那么之后都是9

假如K[i-1]不是3,6,9,那么从i开始之后的数字都是0

#include<iostream>

#include<string>

using namespacestd;

int main()

{

      int t;

      string K,theResult;

      bool theForm[10][10] =

      {

            { true, false, false, false, false,false, false, false, false, false },

            { true, true,true, true, true,true,true, true,true, true},

            { true, false,true, true,false,true, true, false,true, true },

            { false, false, false, true, false,false, true, false, false, true },

            { true, false, false, false, true,true, true, true, true, true },

            { true, false, false, false, false,true, true, false, true, true },

            { false, false, false, false, false,false, true, false, false, true },

            { true, false, false, false, false,false, false, true, true, true },

            { true, false, false, false, false,false, false, false, true, true },

            { false, false, false, false, false,false, false, false, false, true }

      };

      cin >> t; int tmp;

      while (t--)

      {

            cin >> K;

            tmp = K.find_first_not_of('0');

            K = K.substr(tmp, K.size() - tmp);

            int i=0;

            tmp = 1;

            theResult.push_back('1');

            for (i = 0; i < K.size(); i++)

            {

                  if (theForm[tmp][K[i] - '0'])

                  {

                       theResult.push_back(K[i]);

                       tmp = K[i] - '0';

                  }

                  else

                  {

                       if (K[i] - '0' > tmp)

                       {

                             int j = K[i] - '0'- 1;

                             while(!theForm[tmp][j]) j--;

                             theResult.push_back(j+ '0');

                             i++;

                             if (j == 0) tmp =0;

                             else tmp = 9;

                             break;

                       }

                       else

                       {

                             if (tmp == 3 || tmp== 6 || tmp == 9)

                             {

                                   int u =theResult.size() - 1;

                                   while(theResult[u] == '3' || theResult[u] == '6' || theResult[u] == '9') { tmp =theResult[u] - '0'; u--; }

                                   theResult =theResult.substr(0, u + 1);

                            

                                   int l = tmp -1;

                                   while(!theForm[theResult[u] - '0'][l]) l--;

                                   theResult.push_back(l+ '0');

                                   i = u+1;

                                   tmp=l==0?0:9;

                                   break;

                             }

                             else

                             {

                                   tmp = 0;break;

                             }

                       }

                  }

            }

            if (i != K.size())

            {

                  for (int j = i; j <K.size(); j++)

                  {

                       theResult.push_back(tmp +'0');

                  }

            }

            cout << theResult.substr(1,theResult.size() - 1)<<endl;

            theResult.clear();

      }

      return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值