题目描述
来源
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的倍数,所以最大是 ⌊ ( 3 ∗ n ) / 5 ⌋ \lfloor(3 * n) / 5 \rfloor ⌊(3∗n)/5⌋。最小是0。因此,和的取值只能是0, 5, 10, 15, …, ⌊ ( 3 ∗ n ) / 5 ⌋ \lfloor(3 * n) / 5 \rfloor ⌊(3∗n)/5⌋ 中的一个。
-
令top_5 = ⌊ ( 3 ∗ n ) / 5 ⌋ \lfloor(3 * n) / 5 \rfloor ⌊(3∗n)/5⌋,t_5 = a1 + a2 + a3。
-
t_5依次取 ⌊ ( 3 ∗ n ) / 5 ⌋ \lfloor(3 * n) / 5 \rfloor ⌊(3∗n)/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
小结
- 第一种解法比第二种解法效率高。原因在于:第一种解法在找到第一个满足要求的组合就结束了,而第二种解法需要穷举全部组合。