C語言程式設計100例之(6):數字反轉

  • 2019 年 11 月 15 日
  • 筆記

例6    數字反轉

題目描述

給定一個整數,請將該數各個位上數字反轉得到一個新數。新數也應滿足整數的常見形式,即除非給定的原數為零,否則反轉後得到的新數的最高位數字不應為零(參見樣例2)。

輸入格式

一個整數 N

輸出格式

一個整數,表示反轉後的新數。

輸入樣例 #1

123

輸出樣例 #1

321

輸入樣例 #2

-380

輸出樣例 #2

-83

        (1)編程思路。

        將一個非負整數number各位上的數字依次分離出來,其操作步驟為:

1)分離出number的個位數,即number%10。

2)將number除以10,作為新的number,即新的number丟掉了個位數。

3)如果number等於0,分離完畢,結束。否則,轉第1)步,繼續顯示。

例如,number=1234,number%10=4, number=1234/10=123,得到數字4;

                        number%10=3, number=123/10=12,得到數字3;

number%10=2, number=12/10=1,得到數字2;

number%10=1, number=1/10=0,得到數字1;結束。

由數字4、3、2、1如何得到整數4321呢?

4321=4*1000+3*100+2*10+1=4*103+3*102+2*10+1

右邊的多項式可以採用秦九韶演算法求解。

設要求解  P=4*103+3*102+2*10+1

可演變為  P=(((0*10+4)*10 +3)*10+2)*10+1。

這樣,可令P初值為0,每給定一個數字a,執行 P=P*10+a 即可。

由數字4、3、2、1得到整數4321的過程描述為:

P=0  ,給出數字4,P= 0*10+4 =4;   之後數字3 , P=4*10+3= 43;

之後數字2,P= 43*10+2 =432;   最後數字1 , P=432*10+1= 4321。

將上述兩個操作結合起來,一邊分離出number的各位上的數字,一邊將其拼到逆序數P上去,這樣可將求number逆序數P的過程寫成一個簡單的循環。

P=0;

While (number!=0)  { p=p*10+number%10;   number=number/10;   }

(2)源程式。

#include <stdio.h>

int main()

{

         int n,m,f;

         scanf(“%d”,&n);

         m=0; f=1;

          if (n<0)

         {

                   n=-n;

                   f=-1;

         }

         while (n!=0)

         {

                   m=m*10+n%10;

                   n/=10;

         }

         m=f*m;

         printf(“%dn”,m);

         return 0;

}

習題6

6-1  迴文數的個數

題目描述

 “迴文”是指正讀反讀都能讀通的句子,它是古今中外都有的一種修辭方式和文字遊戲,如“我為人人,人人為我”等。在數學中也有這樣一類數字有這樣的特徵,稱為迴文數(palindrome number)。

設n是一任意自然數。若將n的各位數字反向排列所得自然數n1與n相等,則稱n為一迴文數。例如,若n=1234321,則稱n為一迴文數;但若n=1234567,則n不是迴文數。

例如,10到100之間的迴文數有11,22,33,44,55,66,77,88,99共9個。

輸入格式

兩個整數a和b(10≤a≤b≤65535)。

輸出格式

一個整數,表示整數a和b之間所有迴文數的個數。

輸入樣例

10  100

輸出樣例

9

        (1)編程思路。

        一個正整數如果其逆序數與其相等,則它一定是一個迴文數。按例6的方法編寫一個函數int inverse(int n)求整數n的逆序數。

        (2)源程式。

#include<stdio.h>

int inverse(int n)

{

    int s=0;

    while (n!=0)

    {

        s=s*10+n%10;

        n/=10;

    }

    return s;

}

int main()

{

         int a,b,cnt,i;

         while(scanf(“%d%d”, &a,&b)!=EOF)

         {

                   cnt=0;

                   for (i=a;i<=b;i++)

                          if (i==inverse(i)) cnt++;

                   printf(“%dn”, cnt);

         }

         return 0;

}

6-2  迴文數猜想

        本題選自杭州電子科技大學OJ題庫 (http://acm.hdu.edu.cn/showproblem.php?pid=1282)

Problem Description

一個正整數,如果從左向右讀(稱之為正序數)和從右向左讀(稱之為倒序數)是一樣的,這樣的數就叫迴文數。任取一個正整數,如果不是迴文數,將該數與他的倒序數相加,若其和不是迴文數,則重複上述步驟,一直到獲得迴文數為止。例如:68變成154(68+86),再變成605(154+451),最後變成1111(605+506),而1111是迴文數。於是有數學家提出一個猜想:不論開始是什麼正整數,在經過有限次正序數和倒序數相加的步驟後,都會得到一個迴文數。至今為止還不知道這個猜想是對還是錯。現在請你編程式驗證之。

Input

每行一個正整數。

特別說明:輸入的數據保證中間結果小於2^31。

Output

對應每個輸入,輸出兩行,一行是變換的次數,一行是變換的過程。

Sample Input

27228

37649

Sample Output

3

27228—>109500—>115401—>219912

2

37649—>132322—>355553

         (1)編程思路。

         同樣編寫一個函數int inverse(int n)求整數n的逆序數。

        (2)源程式。

#include<stdio.h>

int inverse(int n)

{

    int s=0;

    while (n!=0)

    {

        s=s*10+n%10;

        n/=10;

    }

    return s;

}

int main()

{

    int m,cnt,t;

    while(scanf(“%d”,&m)!=EOF)

    {

        cnt=0;

        t=m;

        while (t!=inverse(t))

        {

            cnt++;

            t=t+inverse(t);

        }

        printf(“%dn”,cnt);

        printf(“%d”,m);

        while (cnt–)

        {

            m=m+inverse(m);

            printf(“—>%d”,m);

        }

        printf(“n”);

    }

    return 0;

}

6-3  叛逆的小明

         本題選自杭州電子科技大學OJ題庫 (http://acm.hdu.edu.cn/showproblem.php?pid=4554)

Problem Description

叛逆期的小明什麼都喜歡反著做,連看數字也是如此(負號除外),比如:小明會把1234它看成4321;把-1234看成-4321;把230看成032 (032=32);把-230看成-032(-032=-32)。

現在,小明做了一些a+b和a-b的題目(a, b為整數且不含前導0),如果給你這些題目正確的答案,你能猜出小明會做得到什麼答案嗎?

Input

輸入第一行為一個正整數T(T<=10000),表示小明共做了T道題。

接下來T行,每行是兩個整數x,y(-1000000<=x, y<=1000000), x表示a+b的正確答案,y表示a-b的正確答案。

輸入保證合法,且不需考慮a或b是小數的情況。

Output

輸出共T行,每行輸出兩個整數s t,之間用一個空格分開,其中s表示小明將得到的a+b答案,t表示小明將得到的a-b答案。

Sample Input

3

20 6

7 7

-100 -140

Sample Output

38 24

7 7

-19 -23

        (1)編程思路。

         由於輸入的x和y是正確答案,即x=a+b ,y=a-b。 可求得 a=(x+y)/2,b=(x-y)/2。

        分別求得a和b的逆序數c和d,這是小明的運算數,輸出c+d和c-d即可。

       (2)源程式。

#include<stdio.h>

int inverse(int n)

{

    int s=0;

    while (n!=0)

    {

        s=s*10+n%10;

        n/=10;

    }

    return s;

}

int main()

{

         int x,y,a,b,c,d,t;

         scanf(“%d”, &t);

         while(t–)

         {

                   scanf(“%d %d”, &x, &y);

                   a = (x +y) / 2;

                   b = (x – y) / 2;

                   if (a < 0)

                            c = -1*inverse(-a);

                   else

                            c = inverse(a);

                   if (b < 0)

                            d = -1*inverse(-b);

                   else

                            d = inverse(b);

                   printf(“%d %dn”, c + d, c – d);

         }

         return 0;

}