包子凑数——蓝桥杯真题Python
包子凑数
输入输出样例
示例 1
输入
2
4
5
输出
6
样例说明
凑不出的数目包括:1, 2, 3, 6, 7, 11。
示例 2
输入
2
4
6
输出
INF
样例说明
所有奇数都凑不出来,所以有无限多个
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
最大公约数
最大公约数:Greatest Common Divisor,GCD,指两个或多个整数共有约数中的最大值。
计算方法:
-
质因数分解法:将各数分解为质因数,取共有质因数的最小幂次乘积。
例如,求36和48的GCD:
36=2^2 * 32,48=24 * 3^1
GCD=22*31=12
-
辗转相除法(欧几里得算法):基于定理 gcd (a,b)=gcd (b,a mod b),迭代至余数为零。
例如,求 1071 和 462 的 GCD:
1071 ÷ 462 = 2(余 147)→ gcd (462,147)
462 ÷ 147 = 3(余 21)→ gcd (147,21)
147 ÷ 21 = 7(余 0)→ GCD 为 21
裴蜀定理
- 定理内容:对于多个整数,若其GCD为d,则它们线性组合的所有可能结果均为d的倍数。
- 无限不可凑数判定:若所有整数的GCD大于1,则只能凑出d的倍数,此时就有无限多 无法凑出的数目,如GCD=2,那么所有的奇数都无法凑出。
- 有限不可凑数判定:若GCD为1,则存在一个最大不可凑数M,超过M的所有数均可被凑出,
解题步骤
- 首先输入n和数组A
- 情况一:若数组A中包含1,那么说明任何数都能凑,打印0.
- 情况二:GCD!=1,则说明有无数个无法凑出的数,打印INF。
- 情况三:GCD==1,则进入动态规划步骤。
import math
def main():
n = int(input())
A = [[int(input())] for _ in range(n)]
if 1 in A:
print("0")
return
g = A[0]
for a in A:
g = math.gcd(a,g)
if g != 1 :
print("INF")
return
else :
maxSize = 10000
dp = [False] * (maxSize + 1)
dp[0] = True
for i in range(1, maxSize+1):
if dp[i]:
for a in A:
if i+a < maxSize+1:
dp[i+a] = True
result = 0
for i in dp:
if i == False:
result += 1
print(result)
return
if __name__ == "__main__":
main()