題意:
給一個數字,問說他的下個回文數字是哪個
回文數字是指正著看跟反著看都相同
ex 1,2,121,1221
解法:
可以分三種情況
1.數字皆為9 ,ex: 999:
如果有n個9,答案是 10..01(中間有n-1個0)
2.從中間開始往左往右看,第一個左右不同的數字左邊比較大,ex: 1321(3>2),3112(3>2),13125(3>2)
可以直接把左邊複製貼上給右邊就是答案, ex: 1321->1331, 3112->3113, 13125->13131
3.從中間開始往左往右看,第一個左右不同的數字右邊比較大或數字本身是回文,ex 1231(2<3),294(2<4),52131(2<3),121,1991,
從中間加一(如果偶數位則加靠左的中間),進位直到不行進位為止,然後左邊複製給右邊,ex 1231->1331, 294->303,52131->52225,121->131,1991->2002
為什麼這樣會是最少步?因為左邊是位數比較大的,所以能不動就不動比較好,所以如果可以直接把左邊複製給右邊,一定會是接下來的回文數字;2.的情況因為右邊較大位數的比較小,所以右邊可以直接加上一些數變成左邊;3.的情況因為右邊較大的位數比較大,沒辦法直接變左邊,所以只好先把左邊加一,確定新數字會比舊數字大,然後再貼過去
程式碼:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
char num[2000002];
int main(){
int len;
int i,j;
gets(num);
while(gets(num)){
len = strlen(num);
for(i=0;i<len&&num[i]=='9';++i);
if(i>=len){
putchar('1');
for(i=1;i<len;++i)putchar('0');
puts("1");
continue;
}
for(i=(len-1)/2,j=(len)/2;i>0&&num[i]==num[j];--i,++j);
if(num[i]<=num[j]){
for(i=(len-1)/2;i>=0;--i){
if(num[i]=='9'){
num[i] = '0';
}else {
num[i] = num[i]+1;
break;
}
}
}
for(i=(len-1)/2,j=(len)/2;i>=0;--i,++j){
num[j]=num[i];
}
puts(num);
}
return 0;
}