关于购买若干香波(15元/个)、香皂(2元/个)、牙刷(5元/个)刚好花完100元的程序设计
for i in range(1,(100-2-5)//15):
for j in range(1,(100-2-i*15)//5+1):
for k in range(1,(100-i*15-j*5)//2+1):
if (15*i+5*j+2*k)==100:
print(i,j,k)
制作一个有3层 for in
循环的嵌套,
for i
for j
for k
其中,i
是香波的循环,j
是牙刷的循环,k
是香皂的循环,
for
i
in range(1,(100-2-5)//15+1):
(100-2-5)//15+1
表示:至少购买了一个香皂(2元/个)、一个牙刷(5元/个)的情况下,可以购买香波(15元/个)的最大数量,即i
的可取的最大值
,
注意:
- “// ”表示的是整除
- for in 循环中的 range 是左闭右开的区间,要想取到整除后的结果,就必须+1(这个加1很重要,它是循环次数变量
i
的取值范围里最大的那个值,取值范围是保证程序有解的前提,如果不加1,程序运行的结果是一个解都没有的,所以,对于设计程序的逻辑的严谨性要足够重视)
for
j
in range(1,(100-2-i*15)//5+1):
(100-2-i*15)//5+1
表示:至少购买了一个香皂(2元/个)情况下,又购买i
个香波(15元/个)后,可以购买牙刷(5元/个)的最大数量,
注意:
j
的取值范围,右参的值要 +1,这样才能取到整除后的值,不加1的话程序运行就没有解,
for
k
in range(1,(100-i15-j5)//2+1):
(100-i*15-j*5)//2+1
表示:在购买了i
个香波(15元/个)和j
个牙刷(5元/个)后,可以购买香皂(2元/个)的最大数量,
由于对嵌套的每层循环中其最大循环值的巧妙设计,这个程序还是比较严谨的,三个嵌套的 for in 循环所执行的循环次数相对是比较合理的(即对计算的结果来说无效循环次数更少,因此程序执行的时间更少)
程序的执行结果如下:
1 1 40
1 3 35
1 5 30
1 7 25
1 9 20
1 11 15
1 13 10
1 15 5
2 2 30
2 4 25
2 6 20
2 8 15
2 10 10
2 12 5
3 1 25
3 3 20
3 5 15
3 7 10
3 9 5
4 2 15
4 4 10
4 6 5
5 1 10
5 3 5
这个程序中对 j
循环其最大循环次数的设计是最难理解的,
程序其实还可以写成如下:
for i in range(1,100//15):
for j in range(1,100//5):
for k in range(1,100//2):
if (15*i+5*j+2*k)==100:
print(i,j,k)
程序执行后也能得到正确的结果,但是,程序会执行了很多次的无效循环导致程序花费了更多的时间猜得到结果,这是因为每层循环取的都是100元能买到的该循环中对应的单品的最大数量,而没有考虑到其他两个商品数量对本层循环次数的影响,所以就导致了每层循环中程序执行了很多个多余的循环计算,影响了程序运行的效率,
那么,我们就要想办法减少每层循环的次数,去掉不合理且无用的循环,
for i
in range(1,(100-2-5)//15+1):
(100-2-5)//15+1
对于 i
循环,(100-2-5)
保证了至少购买了一个香皂(2元/个)、一个牙刷(5元/个),剩下的可以买香波(15元/个)的钱数,再去计算能买香波(15元/个)的个数,也即循环的最大次数就很合理了,
for k
in range(1,(100-i15-j5)//2+1):
(100-i*15-j*5)//2+1
对于 k
循环,(100-i*15-j*5)
是在购买了 i
个香波(15元/个)和 j
个牙刷(5元/个)后,可以买牙刷(5元/个)的余钱,再计算出来的可以购买的牙刷(5元/个)数量,就可以让 k
循环减少很多次无效的循环,
同理,对 j
循环也是一样的理解,
总之,能够合理的减少循环的次数,可以大大提高程序运行的效率。
August2024the18thSunday