【蓝桥杯】买不到的数目

小明开了一家糖果店。

他别出心裁:把水果糖包成4颗一包和7颗一包的两种。

糖果不能拆包卖。

小朋友来买糖的时候,他就用这两种包装来组合。

当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。

你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。

大于17的任何数字都可以用4和7组合出来。

本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。


输入格式

两个正整数 n,mn,m,表示每种包装中糖的颗数。

输出格式

一个正整数,表示最大不能买到的糖数。

数据范围

2≤n,m≤10002≤n,m≤1000,
保证数据一定有解。

输入样例:

4 7

输出样例:

17

一、代码解析

1、解法一

  • 保证数据一定有解,两个数字必须互质,可以保证有解且解的数目无穷
  • 利用最大公倍数,m和n无论怎么组合都必定会得到最大公倍数,即可推出 a * x +b *y的上界是m * n
m,n = map(int,input().split())
set1 = set() #建立空集合
for x in range(n):  #n是表示当x为n时,y为0,可以得到x*n = m*n,即他的最小公倍数(可看为边缘)
    for y in range(m):  # 同理y = m时,x为0时,也是可看为边缘
        if m * x + y * n <= m * n:  
            set1.add(m * x + y * n) #每一个可用n,m组合得到的数放入集合中
i = m * n - 1  #因为上面m和n为循环右开,即add到集合中没有m*n
while i > 0:   #从后面数回来,可率先找到最大的
    if not i in set1:  #查找i是否在集合中,即找到最大不在集合中的数
        break  #循环结束
    i -= 1
print(i) #将第一个找到不在集合中的最大数打印,即买不到的数

2、解法二

(虽然我也不太清楚欧几里得

m,n = map(int,input().split())
print(m*n-(m+n))  #利用数论,欧几里得定理

二、需要注意的细节

1、区分空集合 和 字典

  • 建立空集合是set(),集合里有存放数据才是{2,4,5}
  • 建立字典是{},字典里存放数据是键值对

2、字典查找比列表count查找的可取之处

  • (最快)字典查找是 num in set (num是否在字典里)
  • (快)列表查找是 num in li (num是否在列表li里)
  • (超时)列表查找 li.count(num) == 0 (num在列表的数目为0)

参考:

https://blog.csdn.net/weixin_39969953/article/details/110771742

3、 补充一下集合set的使用

  • set是无序的,没有下标
  • 增 :set.add(x)
  • 删 : set.pop() 随机删除一个元素
  • 改:改不了无序的
  • 查: num in set
  • 且在集合中没有重复的元素

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值