PAT Basic 1079. 延遲的回文數(shù) (20)(C語(yǔ)言實(shí)現(xiàn))

我的PAT系列文章更新重心已移至Github,歡迎來(lái)看PAT題解的小伙伴請(qǐng)到Github Pages瀏覽最新內(nèi)容。此處文章目前已更新至與Github Pages同步。歡迎star我的repo

題目

給定一個(gè) k+1 位的正整數(shù) N ,寫(xiě)成 a_k \cdots a_1 a_0 的形式,其中對(duì)所有 i0 \le a_i < 10
a_k > 0N 被稱(chēng)為一個(gè) 回文數(shù) ,當(dāng)且僅當(dāng)對(duì)所有 ia_i = a_{k-i} 。零也被定義為一個(gè)回文數(shù)。

非回文數(shù)也可以通過(guò)一系列操作變出回文數(shù)。首先將該數(shù)字逆轉(zhuǎn),再將逆轉(zhuǎn)數(shù)與該數(shù)相加,如果和還不是一個(gè)回文數(shù),就重復(fù)這個(gè)逆轉(zhuǎn)再相加的操作,直到一個(gè)回文數(shù)出現(xiàn)。如果一個(gè)非回文數(shù)可以變出回文數(shù),就稱(chēng)這個(gè)數(shù)為
延遲的回文數(shù) 。(定義翻譯自 https://en.wikipedia.org/wiki/Palindromic_number

給定任意一個(gè)正整數(shù),本題要求你找到其變出的那個(gè)回文數(shù)。

輸入格式:

輸入在一行中給出一個(gè)不超過(guò)1000位的正整數(shù)。

輸出格式:

對(duì)給定的整數(shù),一行一行輸出其變出回文數(shù)的過(guò)程。每行格式如下

A + B = C

其中 A 是原始的數(shù)字,BA 的逆轉(zhuǎn)數(shù),C 是它們的和。A 從輸入的整數(shù)開(kāi)始。重復(fù)操作直到 C 在 10
步以?xún)?nèi)變成回文數(shù),這時(shí)在一行中輸出 C is a palindromic number.;或者如果 10 步都沒(méi)能得到回文數(shù),最后就在一行中輸出
Not found in 10 iterations.

輸入樣例 1:

97152

輸出樣例 1:

97152 + 25179 = 122331
122331 + 133221 = 255552
255552 is a palindromic number.

輸入樣例 2:

196

輸出樣例 2:

196 + 691 = 887
887 + 788 = 1675
1675 + 5761 = 7436
7436 + 6347 = 13783
13783 + 38731 = 52514
52514 + 41525 = 94039
94039 + 93049 = 187088
187088 + 880781 = 1067869
1067869 + 9687601 = 10755470
10755470 + 07455701 = 18211171
Not found in 10 iterations.

思路

這道題寫(xiě)起來(lái)有一個(gè)小點(diǎn)令我很頭疼,不過(guò)總體來(lái)說(shuō)還是很簡(jiǎn)單。

整體思路就是,循環(huán):

  • 把A反轉(zhuǎn),得到B
  • 相加A和B,得到C
  • 判斷C是否是回文數(shù)

為了包含進(jìn)A本身就是回文數(shù)的特殊情況,可以在第一步判斷A是否是回文數(shù)。

然后就是具體的每一步的實(shí)現(xiàn):

  • 翻轉(zhuǎn)一個(gè)數(shù),reverseAtoB,將A翻轉(zhuǎn),結(jié)果存儲(chǔ)在B中,實(shí)現(xiàn)很簡(jiǎn)單。
    • 不過(guò)要說(shuō)一點(diǎn),我并沒(méi)有每次在B字符串的末尾加上'\0',是因?yàn)槲页跏蓟珵?code>\0,并且此題的情況中字符串不會(huì)縮短,因此不加不會(huì)有錯(cuò)誤,但是在更廣泛的用途中極有可能產(chǎn)生bug。
  • 兩數(shù)相加,addBtoA,將A和B相加,結(jié)果存儲(chǔ)在A中,這個(gè)就是讓我有點(diǎn)頭疼的。由于題目要求數(shù)字只能用字符串存儲(chǔ),那么原地做加法的話,最后如果要進(jìn)位,前面就沒(méi)有位置了啊。最后還是硬著頭皮暴力地把所有位后移(使用了memmove函數(shù)),因此看起來(lái)并不是很簡(jiǎn)潔。
  • 判斷是否是回文數(shù),isPalindromicNumber,也很簡(jiǎn)單。

簡(jiǎn)單的說(shuō)一下為什么字符串長(zhǎng)度用1011:
初始數(shù)字最多1000位,每次翻轉(zhuǎn)相加,對(duì)于任何數(shù)都不會(huì)增大10倍以上(如10009+90001=100010,很接近10倍),因此10次之內(nèi)得到的結(jié)果絕對(duì)不會(huì)超出1010位,因此字符串就用了char[1011]。

代碼

最新代碼@github,歡迎交流

#include <stdio.h>
#include <string.h>

int isPalindromicNumber(char n[])
{
    int len = strlen(n);
    for(int i = 0; i < len / 2; i++)
        if(n[i] != n[len - i - 1])
            return 0;
    return 1;
}

void addBtoA(char a[], char b[])
{
    /* Assume length of a and b are the same */
    int len = strlen(a), sum, carry = 0;
    for(int i = len - 1; i >= 0; i --)
    {
        sum = a[i] - '0' + b[i] - '0' + carry;
        a[i] = sum % 10 + '0';
        carry = sum / 10;
    }
    if(carry) /* Length of a + b is larger than a or b */
    {
        memmove(a + 1, a, len + 1); /* Shift to right by 1 */
        a[0] = carry + '0';         /* Add the carry to beginning */
    }
}

void reverseAtoB(char a[], char b[])
{
    int len = strlen(a);
    for(int i = 0; i < len; i++)
        b[len - i - 1] = a[i];
}

int main()
{
    int i;
    char a[1011] = {0}, b[1011] = {0};

    scanf("%s", a);
    for (i = 0; i < 10 && !isPalindromicNumber(a); i++)
    {
        reverseAtoB(a, b);
        printf("%s + %s = ", a, b);
        addBtoA(a, b);
        printf("%s\n", a);
    }

    if(i == 10)
        printf("Not found in 10 iterations.");
    else
        printf("%s is a palindromic number.", a);

    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容