我的PAT系列文章更新重心已移至Github,歡迎來(lái)看PAT題解的小伙伴請(qǐng)到Github Pages瀏覽最新內(nèi)容。此處文章目前已更新至與Github Pages同步。歡迎star我的repo。
題目
給定一個(gè) 位的正整數(shù)
,寫(xiě)成
的形式,其中對(duì)所有
有
且 。
被稱(chēng)為一個(gè) 回文數(shù) ,當(dāng)且僅當(dāng)對(duì)所有
有
。零也被定義為一個(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ù)字,B
是 A
的逆轉(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。
- 不過(guò)要說(shuō)一點(diǎn),我并沒(méi)有每次在B字符串的末尾加上
- 兩數(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;
}