python3练习-华为机试

文章讨论了一个使用不同重量和数量的砝码来称重的问题,目标是找出所有可能的不同重量组合。通过Python代码展示了如何解决这个问题,但原始实现导致了内存超限,于是进行了优化,减少了内存使用并避免了重复计算。

HJ41 称砝码

描述

现有n种砝码,重量互不相等,分别为 m1,m2,m3…mn ;
每种砝码对应的数量为 x1,x2,x3...xn 。现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。

注:

称重重量包括 0

数据范围:每组输入数据满足 1≤n≤10 1≤n≤10  , 1≤mi≤2000 1≤mi​≤2000  , 1≤xi≤10 1≤xi​≤10 

输入描述:

对于每组测试数据:
第一行:n --- 砝码的种数(范围[1,10])
第二行:m1 m2 m3 ... mn --- 每种砝码的重量(范围[1,2000])
第三行:x1 x2 x3 .... xn --- 每种砝码对应的数量(范围[1,10])

输出描述:

利用给定的砝码可以称出的不同的重量数

示例1

输入:

2
1 2
2 1

输出:

5

说明:

可以表示出0,1,2,3,4五种重量。   

答题思路:

一种砝码分成若干份(0份,1份,2份,...)

两种砝码的第二种砝码分成若干份(0份,1份,2份,...)

可以表示的重量:

取一种砝码0份、第二种砝码1份;第一种砝码1份,第二种砝码2份....

如:

3种砝码

重量分别是2,4,3

数量分别是2,1,2

①第一份砝码有三种取法,分别是0份(重量0),1份(重量2),2份(重量4);

②第二份砝码有两种取法,分别是0份(重量0),1份(重量4);

③第三份砝码有三种取法,分别是0份(重量0),1份(重量3),2份(重量6);

④总的取法等于各种取法的组合:

只取第一种砝码(2,4);三份都不取(0);

取0份第一种砝码,1份第二种砝码(4);

取1份第一种砝码,1份第二种砝码(6);

取2份第一种砝码,1份第二种砝码(10);

取0份第一种砝码,1份第三种砝码(3);

取1份第一种砝码,1份第三种砝码(5);

取2份第一种砝码,1份第三种砝码(7);

取0份第一种砝码,2份第三种砝码(6);

取1份第一种砝码,2份第三种砝码(8);

以此类推

各种取法交叉组合。

count = int(input())
l_we = []    # 砝码的重量列表
wl_we = input()
wl_we1 = wl_we.split(" ")
for i in range(len(wl_we1)):
    l_we.append(int(wl_we1[i]))
# print(l_we)
l_su = []  # 砝码的数量列表
wl_su = input()
wl_su1 = wl_su.split(" ")
for j in range(len(wl_su1)):
    l_su.append(int(wl_su1[j]))

"""
        思路:
            先拿出第一种[0]砝码的组合数量,作为其实列表
            再从[1]开始,叠加每一种砝码的数量
"""
z = []
for ii in range(l_su[0] + 1):
    z.append(ii * l_we[0])
# print(z)
for jj in range(1, count):
    temp = list(z)
    # print("temp", temp)
    # print("z", z)
    for kk in range(1, l_su[jj] + 1):
        for zz in temp:
            z.append(zz + kk * l_we[jj])
z_sum = sorted(set(z))
# print("长度", len(z_sum))
print(len(z_sum))

本来是上面这样写的,在本地也运行OK,但是在牛客网上提示内存超限,参考代码如下:

修改:

1.输入不再建很多个列表;

2.z定义成集合,本身的元素就没有重复的,后面不需要再一次去重;

3.temp一定要list,如果直接temp = z,直接temp指向z对象,后面z增加,temp也会增加,结果会造成死循环。。。

4.set()增加元素用函数.add(元素);

5.把文字部分、注释全去掉,节省空间;

count = int(input())
l_we = [int(i) for i in input().split()]
l_su = [int(i) for i in input().split()]
z = set()
for ii in range(l_su[0] + 1):
    z.add(ii * l_we[0])
for jj in range(1, count):
    temp = list(z)
    for kk in range(1, l_su[jj] + 1):
        for zz in temp:
            z.add(zz + kk * l_we[jj])
print(len(z))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值