【100个python算法超详细讲解@谷哥技术

 1.问题描述
假设有张、王、李三家,每家都有3个孩子。某一天,这三家的9个孩子一起短跑比
赛,规定不考虑年龄大小,第一名得9分,第二名得8分,第三名得7分,以此类推。比赛
结束后统计分数发现三家孩子的总分是相同的,同时限定这9个孩子的名次不存在并列的
情况,且同一家的孩子不会获得相连的名次。现已知获得第一名的是李家的孩子,获得第
二名的是王家的孩子,要求编程求出获得最后一名的是哪家的孩子。
2.问题分析
根据问题描述可知:
1)参加比赛的一共有9个孩子,得分情况依次是从1~9分。由此可知,该场比赛总共
的分数为9+8+7+6+5+4+3+2+1=45分。
2)由于“比赛结束后统计分数发现三家孩子的总分是相同的”,因此每家孩子的得分
都为15分。
3)由于“获得第一名的是李家的孩子,获得第二名的是王家的孩子”,因此可推知获
得第三名的一定是张家的孩子,否则李家(或王家)的孩子总分就会超过15分。
4)由于“这9个孩子的名次不存在并列的情况,且同一家的孩子不会获得相连的名
次”,因此可推知获得第4名的一定不是张家的孩子。
3.算法设计
将问题分析中的文字进一步具体化。
先确定使用什么结构来存储9个孩子的分数。这里考虑使用列表,设列表名为score,
且score[1]中存放张家3个孩子的分数,score[2]中存放王家3个孩子的分数,score[3]中存放
李家3个孩子的分数。因为“同一家的孩子不会获得相连的名次”,则张家3个孩子的分数分
别按从大到小的顺序依次存放在列表元素score[1][1]、score[1][2]和score[1][3]中,王家3个
孩子的分数分别按从大到小的顺序依次存放在列表元素score[2][1]、score[2][2]和score[2][3]
中,李家3个孩子的分数分别按从大到小的顺序依次存放在列表元素score[3][1]、score[3]
[2]和score[3][3]中。
因此,由问题分析中的第(2)点可知:

score[1][1]+score[1][2]+score[1][3]=15
score[2][1]+score[2][2]+score[2][3]=15
score[3][1]+score[3][2]+score[3][3]=15 

由问题分析中的第(3)点可知:

score[3][1]=9,score[2][1]=8,score[1][1]=7 

由问题分析中的第(4)点可知:

score[1][2]≠6

由于“9个孩子的名次不存在并列的情况,且同一家的孩子不会获得相连的名次”,因
此score列表中存放的9个值应该各不相同,分数为1~9。由①、②可推知:
score[1][2]+score[1][3] ≠score[2][2]+score[2][3] ≠score[3][2]+score[3][3]
因为9个孩子的名次不会并列,且每家孩子的分数是按从大到小的顺序依次存放在列
表中的,因此:
score[1][2] ≠score[2][2] ≠score[3][2]
score[1][3] ≠score[2][3] ≠score[3][3] 
且score[1][2]、score[2][2]、score[3][2]应该占据了分数段的4~6分这几个分值,
score[1][3]、score[2][3]、score[3][3]则占据了分数段的1~3分这几个分值。
由上面的分析可知,由于已经明确了score[1][2]、score[2][2]和score[3][2]这3个列表元
素中存放的值所占据的分数段为4~6分,则可以使用循环结构来判断出3个元素中存放的
值分别是几。判断的依据是在循环体中检测,保证③的成立。
4.确定程序框架
程序的流程图如图6.1所示。

5.完整的程序
根据上面的分析,编写程序如下:

#!/usr/bin/python3
# -*- coding: ?TF-8 -*-
#author: liuhefei
#desc: 谁家孩子跑得最慢
if __name__ == "__main__":
score = [([0] * 4) for i in range(4)] #定义列表,用来存储各个孩子的分数
#score[1]、score[2]和score[3]分别存放张家、王家和李家3个孩子的分数
获得第 名的是李家的孩子 获得第 名的是 家的孩子
#获得第一名的是李家的孩子,获得第二名的是王家的孩子
#初始化三家孩子的最高分数值
score[1][1] = 7 #score[1]存放张家3个孩子的分数
score[2][1] = 8 #score[2]存放王家3个孩子的分数
score[3][1] = 9 #score[3]存放李家3个孩子的分数
#通过循环得到9个孩子的分数
for zhang in range(4, 6):
for wang in range(4, 7):
for li in range(4, 7):
#9个孩子名次不存在并列的情况
if zhang != wang and li != zhang and li != wang \
and 15-zhang-score[1][1] != 15-wang-score[2][1] \
and 15-zhang-score[1][1] != 15-li-score[3][1] \
and 15-wang-score[2][1] != 15-li-score[3][1]:
#将结果存入对应的数组元素
score[1][2] = zhang
score[1][3] = 15-zhang-7
score[2][2] = wang
score[2][3] = 15-wang-8
score[3][2] = li
score[3][3] = 15-li-9
#打印二维数组score,输出各家孩子的分数
print("array score:")
for i in range(1, 4):
for j in range(1, 4):
print(score[i][j], end=' ')
print()
#for循环每一个孩子的分数值,并将最后一名孩子所来自的家庭保存到index中
for n in range(len(score)):
#print(n, score[n])
for m in score[n]:
if m == 1:
index = n #记录最后一名孩子所来自的家庭
#print(index)
#输出最后一名孩子来自的家庭
if index == 1:
print("The last one reached the end is a child from family Zhang.\n")
elif index == 2:
print("The last one reached the end is a child from family Wang.\n")
else:
print("The last one reached the end is a child from family Li.\n")

 在上面的程序中需要注意的是,循环变量zhang可能的取值为4和5,不能为6,这是由
于同一家的孩子不会获得连续的名次。
6.运行结果
在PyCharm下运行程序,结果如图6.2所示。

 

 由运行结果可以看到,我们使用矩阵的形式将三家孩子的分数打印了出来。张家3个
孩子的分数由大到小分别为7分、5分和3分,王家3个孩子的分数由大到小分别为8分、6分
和1分,而李家3个孩子的分数由大到小分别为9分、4分和2分。获得最后一名的孩子也就
是跑得最慢的孩子是王家的孩子。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐