zoukankan      html  css  js  c++  java
  • 输入一个数,找到比该数大的最小回文数

     解题思路主要是从回文数的构造出发,貌似一般与回文数有关的都是构造回文数,而不是去搜索。

     分为多种情况:

    A. 该数的长度是奇数(只有1位很好办,除9外直接加1,9的话输出11),取出该数的前半截(包括中间数),

         1.若该数是回文数,则用前半截数值加1,之后再构造新的回文数;

         2.不是回文数,从中间往两边找到第一个不相等(因为不是回文数,所以肯定能找到)的数,若前面的小于后面的,则按1处理(用前半截数值加1,之后再构造新的回文数);

          若前面的大于后面的,则直接用前半截来构造回文数。

    B. 该数的长度是偶数,取出前半截(正好是一半),思路和奇数的差不多, 如果是回文数或前半截小,则把前半截+1后的数构造回文数;若前半截大,则直接用前半截构造回文数。

    代码: 

      

      1 void ff(int n)          
      2 {
      3     if (n < 0)     
      4     {
      5         cout<<'0'<<endl;
      6         return;
      7     }
      8     char str[20];
      9     char temp[15];
     10     itoa(n,str,10);
     11     int len = strlen(str);
     12     if (len == 1)         //长度为1
     13     {
     14         if (n == 9)           //若n为9 则最近回文数为11
     15         {
     16             cout<<"11"<<endl;
     17         }
     18         else                  //若n比9小 则为n+1
     19         {
     20             cout<<n+1<<endl;
     21         }
     22     }
     23     else if (len%2 == 1)     //长度大于1且为奇数
     24     {
     25         for (int i = 0;i < len/2 + 1;++i)        //保存其前半部分 包括中间数
     26         {
     27             temp[i] = str[i];
     28         }
     29         temp[len/2 + 1] = '\0';
     30         int i,j;
     31         for (i = len/2 -1 ,j = len/2 + 1;j < len;--i,++j)
     32         {
     33             if (str[i] != str[j])
     34             {
     35                 break;
     36             }
     37         }
     38         if (j == len||str[i] < str[j])     //n是回文数 或不是回文数但其前半部分小
     39         {
     40             int num = atoi(temp);       //则前半部分数值+1 再用前半部分构造回文数
     41             ++num;
     42             itoa(num,temp,10);
     43             cout<<num;                        
     44             for (int i = len/2 -1;i >= 0;--i)           
     45             {
     46                 cout<<temp[i];
     47             }
     48             cout<<endl;
     49         }
     50         else                   //不是回文数 但前半部分大
     51         {
     52             cout<<temp;                          //则用前半部分构造回文数
     53             for (int i = len/2 - 1;i >= 0; --i)
     54             {
     55                 cout<<temp[i];
     56             }
     57             cout<<endl;
     58         }
     59     }    
     60     else                   //长度大于1且为偶数
     61     {
     62         for (int i = 0 ; i < len/2 ;++i)       //保存前半部分
     63         {
     64             temp[i] = str[i];
     65         }
     66         temp[len/2] = 0;
     67         if (str[len/2 - 1] == str[len/2])             //有可能是回文数
     68         {
     69             int i,j;
     70             for (i = len/2 - 1,j = len/2;j < len;++j,--i)
     71             {
     72                 if (str[i] != str[j])
     73                 {
     74                     break;
     75                 }
     76             }
     77             if (j == len||str[i] < str[j])  //n是回文数 或不是回文数但其前半部分小
     78             {                                    //则前数加1  用前半部分构造
     79                 int num = atoi(temp);       //则前半部分数值+1 再用前半部分构造回文数
     80                 ++num;
     81                 itoa(num,temp,10);
     82                 cout<<num;                        
     83                 for (int i = len/2 - 1;i >= 0;--i)           
     84                 {
     85                     cout<<temp[i];
     86                 }
     87                 cout<<endl;
     88             }
     89             else                               //不是回文数但其前半部分大
     90             {
     91                 cout<<temp;                   //直接用前半部分构造
     92                 for (int i = len/2 - 1;i >= 0;--i)
     93                 {
     94                     cout<<temp[i];
     95                 }
     96                 cout<<endl;
     97             }
     98         }
     99         else if (str[len/2 - 1] < str[len/2])          //中间靠前的数比后面的小
    100         {                                              //则前数加1  用前半部分构造
    101             temp[len/2 - 1] = char(temp[len/2 - 1] + 1);
    102             cout<<temp;
    103             for (int i = len/2 - 1;i >= 0;--i)
    104             {
    105                 cout<<temp[i];
    106             }
    107             cout<<endl;
    108         }
    109         else                                       //中间靠前的数比后面的大
    110         {                                          //则直接用前半部分构造
    111             cout<<temp;
    112             for (int i = len/2 - 1;i >= 0;--i)
    113             {
    114                 cout<<temp[i];
    115             }
    116             cout<<endl;
    117         }
    118     }
    119     
    120 }

    PS: 花花供题

       

  • 相关阅读:
    P1582 倒水 (二进制)
    P2014 选课 (树形动规)
    多项式前置技能——复数
    P3694 邦邦的大合唱站队 (状压DP)
    P1754 球迷购票问题 (卡特兰数,递推)
    [SCOI2003]字符串折叠 (区间DP)
    [SDOI2008]仪仗队 (欧拉函数)
    4-字符串
    3.输出,输入,基本数据类型
    2.栈,堆,寄存器的理解
  • 原文地址:https://www.cnblogs.com/itachi7/p/2574481.html
Copyright © 2011-2022 走看看