P1149 火柴棒等式,https://www.luogu.org/problem/P1149java
給你n根火柴棍,你能夠拼出多少個形如「A+B=C」的等式?等式中的A、B、C是用火柴棍拼出的整數(若該數非零,則最高位不能是00)。用火柴棍拼數字0-90−9的拼法如圖所示:
python
注意:git
一個整數n(n<=24)。算法
一個整數,能拼成的不一樣等式的數目。ide
樣例1:優化
輸入 14 輸出 2
樣例2code
輸入 18 輸出 9
由於n的最大值只有24,那麼能夠直接提早把答案窮舉出來。blog
# 0-9須要多少根火柴棒 num =[6, 2, 5, 5, 4, 5, 6, 3, 7, 6] # 輸入一個數,計算須要多少火柴棒 def count(x): if x == 0: return 6 c = 0 while x > 0: digit = x % 10 c += num[digit] x = x // 10 return c result = [0] * 24 for n in range(10, 25): #10根火柴如下都是0,很明顯 print("caculate ", n) for i in range(0, 10000): #假設單個數字最大值爲10000 for j in range(0, 10000): if count(i) + count(j) + count(i+j) == n - 4: result[n-1] += 1 print(result)
上述代碼在個人電腦上跑半天也出不來,最大值改爲2000就能夠。一樣的代碼,用Java很快就出結果了,足以說明Python並不適合這一類的題目。get
public class Test { public static void main(String[] args) { int[] result = new int[24]; for(int i = 10; i <= 24; i++) { for(int j = 0; j < 10000; j++) { for(int k = 0; k < 10000; k++) { if(count(j) + count(k) + count(j+k) == i - 4) { result[i] += 1; } } } } for(int i = 0; i < 24; i++) { System.out.println(result[i]); } } public static int[] num = {6,2,5,5,4,5,6,3,7,6}; public static int count(int x) { if(x == 0) { return 6; } int c = 0; while (x > 0) { int digit = x % 10; c += num[digit]; x = x / 10; } return c; } }
最後結果是{0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,8,9,6,9,29,39,38,65,88,128}。input
可是雖然是窮舉,可是上面代碼有個問題,每次都要重複調用count,提早把count存起來就好了,雖然用Python仍是很慢,可是可以在可接受時間內出結果。
# 0-9須要多少根火柴棒 num =[6, 2, 5, 5, 4, 5, 6, 3, 7, 6] # 輸入一個數,計算須要多少火柴棒 def count(x): if x == 0: return 6 c = 0 while x > 0: digit = x % 10 c += num[digit] x = x // 10 return c COUNT = [0] * 20000 for i in range(0, 20000): COUNT[i] = count(i) result = [0] * 24 for n in range(10, 25): print("caculate ", n) for i in range(0, 10000): for j in range(0, 10000): if COUNT[i] + COUNT[j] + COUNT[i+j] == n - 4: result[n-1] += 1 print(result)
沒有什麼更好的方法,咱們能夠儘可能減小循環次數,另外,若是能知道單個數的最大值,那就更好辦了。
要想用最少的火柴棒拼出最大的數,那優先得拼出最大的數字個數,由於999確定要比1111小,由於一個數字至少2個火柴,因此對於偶數個火柴,確定是用拼成11111這樣的最大,例如10根火柴,能拼出的最大數是11111,20個火柴,能拼出的最大數是1111111111。
假設最大值超過10000,那至少須要10根,能拼出11111,剩下10根分紅8+2根,兩個湊起來不可能超過10000,因此最大值不超過10000。
假設最大值可能位於[9000,10000),至少須要12根,能拼出9111,剩下8根不可能加起來等於這個數。
假設最大值可能位於[8000,9000),至少須要13根,更不可能。
假設最大值可能位於[7000,8000),至少須要9根,也就是7111,剩下11根,,若是分紅9+2,2根只能是1,因此9根必須拼成7110,不夠數。
假設最大值可能位於[6000,7000),至少須要12根,剩下8根也不行。
假設最大值可能位於[5000,6000),至少須要11根,剩下9根能拼出的最大4位數是7xxx或者1xxx,加起來不多是5000。對於[2000,5000)也同樣。
假設最大值可能位於[1900,2000],那麼最少須要12根,1911,剩下的無法相加爲1911。
依次分析,咱們發現最大數不可能大於1111。經過程序結果來看,最大值爲712。
改進以後,不用打表也能AC。
# 0-9須要多少根火柴棒 num =[6, 2, 5, 5, 4, 5, 6, 3, 7, 6] # 輸入一個數,計算須要多少火柴棒 def count(x): if x == 0: return 6 c = 0 while x > 0: digit = x % 10 c += num[digit] x = x // 10 return c COUNT = [0] * 713 for i in range(0, 713): COUNT[i] = count(i) result = 0 n = int(input()) for i in range(0, 712): for j in range(0, 712): if i + j > 712: continue if COUNT[i] + COUNT[j] + COUNT[i+j] == n - 4: result += 1 print(result)