題目
問題描述 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)
我們觀察兩處代碼的差異,其實只在對列表排序的時候將元素轉成整型而已,至於為什么會得到不同的結果我想不清楚,如果有知道原因的讀者煩請私聊我或者在下面留言。