完整源代码项目地址,关注博主私信'源代码'后可获取
1.问题描述 2.问题分析 3.算法设计 4.确定程序框架 5.完整的程序 6.运行结果
1.问题描述
马克思手稿中有一道趣味数学问题:有30个人,其中有男人、女人和小孩,他们在同一家饭馆吃饭,总共花了50先令。已知每个男人吃饭需要花3先令,每个女人吃饭需要花2先令,每个小孩吃饭需要花1先令,请编程求出男人、女人和小孩各有几人。
2.问题分析
根据该问题的描述,可将该问题抽象为一个不定方程组。
设变量x、y和z分别代表男人、女人和小孩,则由题目的要求,可得到如下的方程组:
{ x + y + c = 30 1 ◯ 3 x + 2 y + z = 50 2 ◯ \begin{cases}x+y+c=30 &&&&&& \textcircled{1}\\3x+2y+z=50 &&&&&& \textcircled{2}\\\end{cases} { x + y + c = 30 3 x + 2 y + z = 50 1 ◯ 2 ◯
其中,方程①表示男人、女人和小孩加起来总共有30个人;方程②表示30个人吃饭总共花了50先令。
用方程②-方程①,可得:
2x+y=20 ③
由方程③可知,x取值范围为[0,10]。
3.算法设计
在问题分析中,我们抽象出了一个不定方程组,显然得到了不定方程组的解,该问题也就解决了。但不定方程组中包含了x、y、z三个变量,而方程只有两个,因此不能直接求出x、y、z的值。
而由方程③,我们得到了x的取值范围,因此可将x的有效取值依次代入不定方程组中(即方程①、②、③)中,能使三个方程同时成立的解即为该问题的解。为实现该功能,只需使用一个for循环语句即可。
4.确定程序框架
不定方程组的求解过程代码如下:
for x in range ( 0 , 10 + 1 ) : y = 20 - 2 * x z = 30 - x - y if 3 * x + 2 * y + z == 50 : number += 1 print ( "%2d:%4d%5d%6d" % ( number, x, y, z) )
上面的代码中对于for循环中每个给定的x值,可先通过方程③确定y值,再将当前确定的x和y值代入方程①中确定z值。此时,变量x、y、z都有确定的值了,但它们的值的组合不一定是不定方程组的解,还需要代入方程②中进行验证,只有同时满足方程①、②、③的解才是不定方程组的解。
程序流程图如图所示。
5.完整的程序
根据上面的分析,编写程序如下:
% % time
if __name__== "__main__" : print ( " Men Women Children " ) number = 0 for x in range ( 0 , 10 + 1 ) : y = 20 - 2 * x z = 30 - x- yif 3 * x + 2 * y + z == 50 : number += 1 print ( "%2d:%4d%5d%6d" % ( number, x, y, z) )
Men Women Children 1: 0 20 102: 1 18 113: 2 16 124: 3 14 135: 4 12 146: 5 10 157: 6 8 168: 7 6 179: 8 4 18
10: 9 2 19
11: 10 0 20
CPU times: user 527 µs, sys: 14 µs, total: 541 µs
Wall time: 336 µs
6.运行结果
由输出结果可知,该不定方程组的解共有11组,即男人、女人和小孩的可能组合共有11种情况。