題目
問題描述
123321是一個非常特殊的數,它從左邊讀和從右邊讀是一樣的。
輸入一個正整數n, 編程求所有這樣的五位和六位十進制數,滿足各位數字之和等於n 。
輸入格式
輸入一行,包含一個正整數n。
輸出格式
按從小到大的順序輸出滿足條件的整數,每個整數佔一行。
樣例輸入
52
樣例輸出
899998
989989
998899
數據規模和約定
1<=n<=54。
解法一
我們首先想到的就是遍歷所有五位數和六位數,將數字轉成字符串再逆轉然後判斷是否爲迴文數,接着求各位數字之和判斷是否等於n,滿足以上兩個條件就是答案。
n = int(input(''))
for i in range(10000, 1000000):
num = str(i)
s = sum(int(j) for j in num)
if s == n and num == num[::-1]:
print(num)
以上代碼提交顯示運行超時。仔細一想不難發現這裏其實是二重循環,因爲sum()函數求和過程其實也是一個循環,從而導致算法複雜度增大。下面我們看改進代碼:
n = int(input(''))
for i in range(10000, 1000000):
num = str(i)
if num == num[::-1]:
if n == sum(int(j) for j in num):
print(num)
以上代碼顯示通過。因爲這裏的算法複雜度已經降低了很多,我們先判斷是否爲迴文數再來求數字之和,因爲滿足迴文數的數字並不多,因此減少了很多無效的求和運算。
解法二
我們採用逆向思維,先保證是迴文數再判斷數字之和是否等於n。根據迴文數左右兩邊對稱的特點,我們可以將五位數到六位數的循環轉換成三位數到四位數的循環。
n = int(input(''))
x = []
for i in range(100, 1000):
if sum(map(int, str(i) + (str(i)[:2])[::-1])) == n:
x.append(str(i) + (str(i)[:2])[::-1])
if sum(map(int, str(i) + str(i)[::-1])) == n:
x.append(str(i) + str(i)[::-1])
for j in sorted(x):
print(j)
以上代碼得分只有四十分。我們再看下面的改進代碼:
n = int(input(''))
x = []
for i in range(100, 1000):
if sum(map(int, str(i) + (str(i)[:2])[::-1])) == n:
x.append(str(i) + (str(i)[:2])[::-1])
if sum(map(int, str(i) + str(i)[::-1])) == n:
x.append(str(i) + str(i)[::-1])
for j in sorted(map(int, x)):
print(j)
我們觀察兩處代碼的差異,其實只在對列表排序的時候將元素轉成整型而已,至於爲什麼會得到不同的結果我想不清楚,如果有知道原因的讀者煩請私聊我或者在下面留言。