題目描述
來源
OpenJudge網站 —— 百練習題集-第4146號習題
要求
總時間限制: 1000ms 內存限制: 65536kB
描述
如上圖,有3個方格,每個方格里面都有一個整數a1,a2,a3。已知0 <= a1, a2, a3 <= n,而且a1 + a2是2的倍數,a2 + a3是3的倍數, a1 + a2 + a3是5的倍數。你的任務是找到一組a1,a2,a3,使得a1 + a2 + a3最大。
輸入
一行,包含一個整數n (0 <= n <= 100)。
輸出
一個整數,即a1 + a2 + a3的最大值。
樣例輸入
3
樣例輸出
5
解題思路
下面介紹兩種解法。第一種解法比第二種解法效率高,大致快4-5倍。
解法一的思路
-
a1 + a2 + a3的和最大不會超過3 * n。由於和是5的倍數,所以最大是。最小是0。因此,和的取值只能是0, 5, 10, 15, …, 中的一個。
-
令top_5 = ,t_5 = a1 + a2 + a3。
-
t_5依次取, …, 15, 10, 5, 0 。對於每一個t_5,我們窮舉a2, a3的可能組合,找滿足如下條件的組合:
(a2 + a3) % 3 == 0 and (t_5 - a3) % 2 == 0 and (t_5 - a2 - a3) <= n
這裏,t_5 - a3正是a1 + a2,t_5 - a2 -a3正是a1。 -
一旦找到滿足上述條件的t_5, a2, a3組合,我們就找到了和最大的解,正是t_5 。輸出結果後,程序無需繼續尋找,可以結束了。
解法二的思路
- a1依次取n, n-1, …, 0;對於每一個a1,a2依次取n, n-1, …, 0;對於每一組a1, a2,a3依次取n, n-1, …, 0,這樣窮舉了a1, a2, a3的所有組合。
- 對於滿足“a1 + a2是2的倍數,a2 + a3是3的倍數, a1 + a2 + a3是5的倍數“的組合,求出a1 + a2 + a3之和,找出最大的和即爲結果。
- 由於n<=100,因此上述第1點會重複100 * 100 * 100 =106次,可以接受。
參考答案
解法一的參考答案
n = int(input())
top_5 = (3 * n) // 5 * 5
for t_5 in range(top_5, -1, -5):
for a2 in range(n, -1, -1):
a3_start = min(n, t_5 - a2) #a2 + a3 <= t_5 (=a1 + a2 + a3)
for a3 in range(a3_start, -1, -1):
if (a2 + a3) % 3 == 0 and (t_5 - a3) % 2 == 0 and (t_5 - a2 - a3) <= n:
print(t_5) #找到的第一個就是和最大的解
exit(0) #結束程序。
解法二的參考答案
n = int(input())
total = 0
for a1 in range(n, -1, -1):
for a2 in range(n, -1, -1):
for a3 in range(n, -1, -1):
if (a1 + a2) % 2 == 0 and (a2 + a3) % 3 == 0 and (a1+a2+a3) % 5 == 0 and a1+a2+a3 > total:
total = a1 + a2 + a3 #找到更大的和
print(total)
測試用例
-
題目給出的測試用例覆蓋了n較小的情形。
-
n=2。
樣例輸入
2
樣例輸出
5
說明:a1=2, a2=2, a3=1 -
n=100。
樣例輸入
100
樣例輸出
295
說明:a1=100, a2=100, a3=95。易知結果爲300是不成立的,接下來就是295,沒問題。 -
n=0 。
樣例輸入
0
樣例輸出
0 -
n=1 。
樣例輸入
0
樣例輸出
0
小結
- 第一種解法比第二種解法效率高。原因在於:第一種解法在找到第一個滿足要求的組合就結束了,而第二種解法需要窮舉全部組合。