day05-分支与循环的运用
案例1.百鸡百钱问题
公鸡5元一只,母鸡3元一只,小鸡1元三只,欲用100元买100只鸡,问公鸡、母鸡、小鸡各多少只?
# 5,3,1/3
# 5x+3y+1/3*z=100 x+y+z=100
# 15x+9y+z=300 x+y+z=100
# 14x+8y=200 x+y<=100
for i in range(21):
for j in range(100 - i + 1):
if i * 14 + j * 8 == 200:
print(f'公鸡买{i}只,母鸡买{j}只,小鸡买{100 - i - j}只')
穷举法:穷尽所有的可能性直到找到正确答案 - 暴力搜索法
使用穷举法的时候注意可以通过限制条件来避免执行不必要的循环来加快程序运行的效率。
案例2.分鱼问题
有ABCDE五个人去捕鱼,捕完鱼太累倒头睡觉。
第二天,A第一个醒过来,他把鱼分成5份,扔掉多余的1条,拿走自己的一份;
B第二个醒过来,他以为鱼还没有分过,把剩下的鱼分成5份,扔掉多余的1条,拿走自己的一份;
C、D、E依次醒过来,都是按照上面的方法,把鱼分成5份,扔掉多余的1条,拿走自己的一份。
问,他们最少捕了多少条鱼?
all_fish = 1
fish = 0
# 穷举
while True:
right = True
all_fish += 5
fish = all_fish
# 模拟分鱼过程
for _ in range(5):
if (fish - 1) % 5 == 0:
fish = ((fish - 1) // 5)*4
else:
right = False
if right:
print(f'最少捕了{all_fish}条鱼')
break
案例3.CRAPS赌博游戏
CRAPS赌博游戏 - 摇两颗色子
玩家摇色子,如果第一次摇出了7点或11点,玩家胜;
如果摇出2点、3点、12点,庄家胜;其他情况,游戏继续,
玩家重新摇色子,如果摇出了第一次摇的点数,玩家胜;
如果摇出了7点,庄家胜;其他情况,游戏继续,玩家重新摇色子,
直到分出胜负。
-
把游戏的场景模拟出来,输出玩家胜还是庄家胜;
-
玩家一开始有1000元,每次玩的时候下注,赢了获得对应的注码;输了就输掉对应的注码;
-
游戏结束的条件是玩家破产。
import random def roll_dice(n): reslut = 0 for _ in range(n): dice = random.randrange(1, 7) reslut += dice return reslut first_point = roll_dice(2) print(f'玩家摇出了{first_point}点。') if first_point in (7, 11): print('玩家胜!!!') elif first_point in (2, 3, 12): print('庄家胜!!!') else: while True: current_point = roll_dice(2) print(f'玩家摇出了{current_point}点。') if current_point == first_point: print('玩家胜!!!') break elif current_point == 7: print('庄家胜!!!') break
对函数进行封装可以减少重复代码
案例4.统计骰子概率
把两颗色子摇10000次,统计每种点数出现的次数和频率
from example03 import roll_dice
a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
for _ in range(10000):
a = roll_dice(2)
if a == 2:
a2 += 1
elif a == 3:
a3 += 1
elif a == 4
a4 += 1
elif a == 5:
a5 += 1
elif a == 6:
a6 += 1
elif a == 7:
a7 += 1
elif a == 8:
a8 += 1
elif a == 9:
a9 += 1
elif a == 10:
a10 += 1
elif a == 11:
a11 += 1
elif a == 12:
a12 += 1
a2 /= 10000
a3 /= 10000
a4 /= 10000
a5 /= 10000
a6 /= 10000
a7 /= 10000
a8 /= 10000
a9 /= 10000
a10 /= 10000
a11 /= 10000
a12 /= 10000
print(a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)
案例5.找出10000以内的完美数。
完美数:如果一个数等于除自身以外所有因子的和,那么这个数就叫完美数。
6 = 1 + 2 + 3
28 = 1 + 2 + 4 + 7 + 14
for num in range(2, 10000):
total = 1
for i in range(2, int(num ** 0.5) + 1):
if num % i == 0:
total += i
if i != num // i:
total += num // i
if total == num:
print(num)
案例6.输出乘法口诀表
for i in range(1, 10):
j = 1
while j < i:
print(f'{j}*{i}={j * i}', end=' ')
j += 1
print(f'{j}*{i}={j * i}')
案例7.输入两个正整数,计算它们的最大公约数和最小公倍数
a = int(input('输入一个数'))
b = int(input('再输入一个数'))
if a < b:
a, b = b, a
for i in range(1, b + 1):
if a * i % b == 0:
print(f'{a * i}为这两个数的最小公倍数')
break
t = b
c = a % b
while c:
t = c
c = t % c
print(f'{t}为这两个数的最大公因数')
案例8.输入10个数计算出算术平均值
n = 10
total = 0
print(f'输入{n}个数')
for i in range(n):
a = float(input(''))
total += a
average = total / n
print(f'平均值为{average:.2f}')
案例9.输入两个正整数n和k,n >= k,计算排列数和组合数
print('输入两个数')
n = int(input())
k = int(input())
total_multiply = 1
total_divide = 1
for i in range(1, n + 1):
total_multiply *= i
for j in range(1, n - k + 1):
total_divide *= j
res_1 = total_multiply / total_divide
print(f'组合数为{res_1}')
total_multiply = 1
total_divide = 1
for i in range(n - k + 1, n + 1):
total_multiply *= i
for j in range(1, k + 1):
total_divide *= j
res_2 = total_multiply / total_divide
print(f'排列数为{res_2}')
案例10.输入三角形三条边的长度,先判断能否构成三角形,如果可以,计算出三角形的周长和面积
print('输入三角形的三条边长')
a = float(input())
b = float(input())
c = float(input())
l = a + b + c
p = l / 2
s = (p * (p - a) * (p - b) * (p - c)) ** 0.5
if b < c:
b, c = c, b
if a < b:
a, b = b, a
if a < b + c:
print('能构成三角形')
print(f'周长为{l},面积为{s}')
else:
print('不能构成三角形')
穷举法:穷尽所有的可能性直到找到正确答案 - 暴力搜索法
使用穷举法的时候注意可以通过限制条件来避免执行不必要的循环来加快程序运行的效率。
封装函数:可以通过调用自己定义函数的方式来减少重复代码
def 函数名():
代码部分
从其他文件中调用自己定义的函数:
from 文件名 import 函数名
range(100,1,-2)取值范围为100-0,步长为-2
计算最小公倍数时:辗转求余数法