題意:

給一個數字,問說他的下個回文數字是哪個

回文數字是指正著看跟反著看都相同

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;
}

arrow
arrow
    全站熱搜

    alan790712 發表在 痞客邦 留言(0) 人氣()