hrbust 1854幼稚园的数学Ⅱ

幼稚园的数学Ⅱ
Time Limit: 1000 MS Memory Limit: 32768 K
Total Submit: 28(10 users) Total Accepted: 8(6 users) Rating:  Special Judge: No
Description
    唉。。自从上次被幼儿园数学虐残之后,小胖子koko觉得自己要开始练习幼儿园数学了,于是他就像幼儿园传奇教父 AK_PUSH前辈请教。 AK_PUSH前辈为了看看小胖子koko是否具有学习幼儿园数学的潜质,给他出了一道题目:给你一个数N找出第一个比N大的回文数。一个数被称为回文数,当且仅当。。。它正反念都一样啦!小胖子koko看了题后haha大笑,这题未免也太水了吧!于是他花了10秒钟写就写完了程序,然后。。。他就来找你炫耀啦!
为了避免被幼儿园小朋友暴虐,你的任务就是,写一个程序,完成 AK_PUSH前辈的题目。
Input
    输入以T开始,代表测试样例的个数(T<=30),每组样例包括一个整数:n(n<10^50000)
Output
    每一组样例,输出符合条件的最小回文数
Sample Input
5
121
1
1332331
11
1121
Sample Output
Case 1: 131
Case 2: 2
Case 3: 1333331
Case 4: 22
Case 5: 1221
Author
小伙伴们@哈商大

题意:求第一个比N大的回文数(N可以是非回文数或回文数)


思路:

这题十分抠细节

假设第一个比N大的回文数是M

△必须达到最小(△=M-N)即增量最小

在改变N的其中一对数字时候从中间开始往左右改数字增量一定是最小的

比如10001可变成10101 11011 明显能看到从中间开始该数字的增量是最小的

因为高位数字的增量一定比低位数字的增量大

修改数字的时候还要注意一些细节

首先要从中间往左右遍历,找出第一对不相等的数字Ai Aj(Ai在高位,Aj在低位),如果Ai>Aj那么把Aj改为Ai(理由见红字),否则把两个数都改为Ai+1,然后剩下每一对不相等的数字Ai Aj都改为Ai Ai

为什么要剩下的每一对都改成和Ai一样的呢

①因为遍历是从中间遍历的,那么保证了增量最小

②当Ai>Aj时,如果把Ai也改为Aj,那最后的数肯定N还要小。当Ai<Aj时,AiAi明显比AjAj的增量小

这里还要注意的是如果第一对不相等的数的位置在len/2+1的话要分情况修改

如 abbc,abc

当a>c时要修改成abba,这里是因为c处在低位b处在高位,如果该成a(b+1)(b+1)a,增量大小可想而知

当a<c时要修改成a(b+1)(b+1)a,这里是因为a处在高位b处在低位,如果改成cbbc,同理...


下面附上不仅长还不优雅的代码

幼稚园的数学题搞了我几个小时,我真是太辣稽了(感觉是自己在讽刺自己......)

#include<cstdio>
#include<cstring>
char s[50005];
int main()
{
    int n;
    while(~scanf("%d",&n))
    for (int k=1;k<=n;k++)
    {
        scanf("%s",s);
        int top=0,ed=strlen(s)-1,len=strlen(s)-1;
        int flag=0;
        if (len==0)
        {
           if (s[0]>='0'&&s[0]<='8') printf("Case %d: %c\n",k,s[0]+1);
           else printf("Case %d: 11\n",k);
           continue;
        }
        if (len&1)
        {
            top=len>>1; ed=top+1;
            while(top>=1&&ed<=len-1)
            {
                if (s[top]==s[ed]) --top,++ed;
                else
                {
                   if (top==len>>1)
                   {
                      if (s[top]=='0') s[ed]=s[top]='1';
                      else s[top]=s[ed]=(s[top]<s[ed]?s[top]+1:s[top]);
                   }
                   else
                   {
                       if (s[top]<s[ed])
                       {
                           s[len>>1]=s[(len>>1)+1]=(s[len>>1]+1);
                           s[ed]=s[top];
                       }
                       else
                        s[ed]=s[top];
                   }
                   flag=1;
                   break;
                }
            }

            while(top>=1&&ed<=len-1)
            {
                if (s[top]!=s[ed])
                   s[top]=s[ed]=(s[top]=='0'?'0':s[top]),flag=1;
                --top,++ed;
            }

            if (flag) s[ed]=s[top];
            else
            {
               if (s[top]>s[ed]) s[ed]=s[top];
               else
               if (s[top]<s[ed])
               {
                  if (top!=len>>1)
                   ++s[len>>1],++s[(len>>1)+1];
                  else s[top]=s[ed]=(s[top]+1);
               }
               else
                if (s[top]==s[ed])
                  ++s[len>>1],++s[(len>>1)+1];
            }

            top=len>>1; ed=top+1;
            --top,++ed;
            while(top>=0&&ed<=len)
            {
                if (s[top+1]>'9')
                {
                    s[top+1]=s[ed-1]='0';
                    s[top]=s[ed]=(s[top]+1);
                }
                --top,++ed;
            }
            if (s[0]>'9') s[0]='0',s[len]='1',printf("Case %d: 1%s\n",k,s);
            else printf("Case %d: %s\n",k,s);
        }
        else
        {
            top=ed=len>>1;
            --top,++ed;
            while(top>=1&&ed<=len-1)
            {
                if (s[top]==s[ed]) --top,++ed;
                else
                {
                    if (s[top]<s[ed]) s[ed]=s[top],++s[len>>1];
                       else s[ed]=s[top];
                   flag=1;
                   break;
                }
            }

            while(top>=1&&ed<=len-1)
            {
                if (s[top]!=s[ed])
                  s[top]=s[ed]=(s[top]=='0'?'0':s[top]),flag=1;;
                --top,++ed;
            }

            if (flag) s[ed]=s[top];
            else
            {
               if (s[top]>s[ed]) s[ed]=s[top];
               else if (s[top]<s[ed]) s[ed]=s[top],++s[len>>1];
               else ++s[len>>1];
            }

            top=ed=len>>1;
            --top,++ed;
            while(top>=0&&ed<=len)
            {
                if (s[top+1]>'9')
                {
                    s[top+1]=s[ed-1]='0';
                    s[top]=s[ed]=(s[top]+1);
                }
                --top,++ed;
            }
            if (s[0]>'9') s[0]='0',s[len]='1',printf("Case %d: 1%s\n",k,s);
            else printf("Case %d: %s\n",k,s);
        }
    }
}



猜你喜欢

转载自blog.csdn.net/qq_38000095/article/details/70795876
今日推荐