HUT-1560 The Least Palindromic Number 模拟
1560: The Least Palindromic Number
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 111 Solved: 15
[Submit][Status][Web Board]
Description
Palindromic numbers are digital strings that read the same both
forwards and backwards. For example, 121, 44 and 3 are Palindromic
numbers, 175, 36 are not;
For a given integer N, you are to find a palindromic number P that
satisfy P>N. However, there are many such palindromic numbers. Your
task is to find the least one.
Input
There are several
test cases, each test case contains only one positive integer N in one
line. The number of digits of N is not exceeding 10,000, and N has not
lead zeroes.
The input will finish with the end of file.
Output
For each the case, your program will output the least palindromic number P (P > N) on separate line.
Sample Input
44
3
195
Sample Output
5
4
202
这题数据解释一切 输入 101 111 1111 999 9999 1110 输出 111 121 1221 1001 10001 1111。这题一定要先分析清楚,不然写道后面代码量会增大,而且会存在漏洞。
这题首先过滤掉特殊数据,那就是只有1位的数和全为9的数据,后面就要分长度为奇数和偶数进行分析,如果为奇数的,那么把串分两部分存储起来,从中间到两端进行比较,这样可以得到一个最接近的数,例如12345 先比较2 和 4, 如果前者比后者大,那么把前面的字符串反转存储到后面的数组中,再将中间的数以及反转后的数组连接到左边的数组上,如果前面的数比后面的数要小的话,那么就会复杂一点了,首先得判定中间的数是否为9,如果不为9的话,很好办,中间数加1再回到上面的情况,如果为9的话,就要进位了,有点类似大数中的进位,反正可以理解为将左边数组加上中间的数加上一个1,在第一种处理方式。长度为偶数的话就是不处理中间的数字就行了。还有一种情况就是如果该串左右对称那么可以将其归类到前面比后面小的那一类,不是吗?因为这里要求我们必须输出比原来要大的数。
代码如下:
#include <stdio.h> #include <string.h> char num[10005], left[10005], right[10005]; void reverse( char *left, char *right, char center, int info ) { int len= strlen( left ); for( int i= len- 1, j= 0; i>= 0; --i, ++j ) { right[j]= left[i]; } if( info ) { left[len]= center, left[ len+ 1 ]= '\0'; } strcat( left, right ); } int main() { while( scanf( "%s", num )!= EOF ) { int len= strlen( num ), cnt= 0; for( int i= 0; i< len; ++i ) { if( num[i]== '9' ) { cnt++; } } if( cnt== len ) { memset( num, '0', sizeof( num ) ); num[0]= num[len]= '1'; num[len+ 1]= '\0'; puts( num ); continue; } if( len== 1 ) { if( num[0]< '9' ) { printf( "%c\n", num[0]+ 1 ); continue; } else { puts( "11" ); continue; } } // 以上为各种特殊处理 int pos= len/ 2, flag= 0, kind; char center= num[pos]; num[pos]= '\0'; strcpy( left, num ); if( len& 1 ) { kind= 1; strcpy( right, num+ pos+ 1 ); } else { kind= 0; num[pos]= center; strcpy( right, num+ pos ); } for( int i= pos- 1, j= 0; i>= 0; --i, ++j ) { if( left[i]== right[j] ) { if( i!= 0 ) { continue; } } else if( left[i]> right[j] ) { flag= 1; reverse( left, right, center, kind ); break; } if( left[i]< right[j]|| i== 0 ) { if( center!= '9'&& len& 1 ) { center+= 1; reverse( left, right, center, kind ); flag= 1; break; } else { center= '0'; int i= pos- 1; left[i]+= 1; while( left[i]> '9' ) { left[i]= '0'; left[i- 1]+= 1; --i; } reverse( left, right, center, kind ); flag= 1; break; } } } if( flag ) { puts( left ); } } }
其实这题应该可以直接用strcmp这个函数来比较的,那样还能简化很多操作。