【Python练习题 017】 两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比。请编程序找出三队赛手的名单。

------------------------------------------------------

这题真真想破我脑袋了,看了好几份别人的代码才勉强看懂,真是…… 一开始我只想着先把所有可能都配出来(ax, ay, az, bx, by, bz, cx, cy, cz),然后根据后面的条件排除不可能的配对。怎么写也写不对。

后来看了别人的代码,结合自己的思考,整理出基本思路如下:假设a,b,c的对手分别是i,j,k,将i,j,k所有可能出现的组合先穷举出来,同时需要满足2个条件:i,j,k不能同时出现(即a,b,c的对手不可能有重复);a不对x,c不对x,z,只要满足此2条件就可以。简而言之:用3个for穷举,用2个if限定条件。代码如下:

for i in range(ord('x'), ord('z')+1):  #假设a,b,c的对手分别是i,j,k
for j in range(ord('x'), ord('z')+1): #用3个for穷举i,j,k可能出现的所有组合
for k in range(ord('x'), ord('z')+1):
if i != j and j != k and k != i: #条件1:i,j,k不能同时出现
if i != ord('x') and k != ord('x') and k != ord('z'): #条件2:a不对x,c不对x,z
print('a vs %s, b vs %s, c vs %s' % (chr(i), chr(j), chr(k)))

输出结果如下:

a vs z, b vs x, c vs y

根据上述代码,联想到之前 求解不重复的3位数 时用到的itertools库,觉得可以简化代码如下:

import itertools

for i in itertools.permutations('xyz'):
if i[0] != 'x' and i[2] != 'x' and i[2] != 'z':
print('a vs %s, b vs %s, c vs %s' % (i[0], i[1], i[2]))

输出结果一样。代码简洁很多,结构也清晰不少。

itertools.permutations()是个好东西,可以直接将'xyz'生成包含所有排列的列表。另外两个相关的库方法分别是:itertools.product()生成笛卡尔数列(即包括所有排列方式,itertools.combinations()生成所有组合的列表。就生成项的数目而言,product() > permutations() > combinations()。本题中,permutations('xyz', 3)可生成6组排列方式,而如果换成combinations('xyz', 3),则只有1种组合方式('x', 'y', 'z')。详见官方文档

【2016-10-17 更新】----------------------------------------------------

感谢 rm-rf 的耐心解答,又多了一种解题思路:先将 a,b,c 这一队列出所有可能的排列方式(共6组),然后每一组都跟 x,y,z 进行匹配(用zip()方法),并设置判断条件。事实证明,这6组之中,只有1组是满足条件的。代码如下:

import itertools

team_1 = ['a', 'b', 'c']
team_2 = ['x', 'y', 'z'] for i in itertools.permutations(team_1, 3):
for j in zip(i, team_2):
if j in [('a','x'),('c','x'),('c','z')]:
break
else:
print(i, team_2)

输出结果如下:

('b', 'c', 'a') ['x', 'y', 'z']

rm-rf 还提供了另一种写法,但是……好吧,还没学到 lambda,自定义函数也还没怎么学,所以根本看不懂…… 但还是很感谢啊!希望过不了多久,我就能看懂了~~~

import itertools

check_list = [('a', 'x'), ('c', 'x'), ('c', 'z')]
for i in itertools.permutations(team_1, 3):
f = lambda a,b: len([True for j in zip(a, b) if j not in check_list])
if f(i, team_2) == 3:
print(i, team_2)

++++++++++++++++++++++++++++++++++++++

题目出处:编程语言入门经典100例【Python版】

最新文章

  1. java核心技术第一卷
  2. UVaLive 7143 Room Assignment (组合数+DP)
  3. 颤抖吧,骚年们,2016年末最牛逼的sql语句
  4. 智能指针 ADO数据库连接
  5. Windows上使用clang编译
  6. Android 编程下的四大组件之服务(Service)
  7. aac格式解析
  8. w-BIG TABLE-view+where-small table
  9. (11)lambda表达式用法
  10. Android 自定义View修炼-Android实现圆形、圆角和椭圆自定义图片View(使用BitmapShader图形渲染方法)
  11. WindowsForm 记事本 对话框
  12. 面试题之——抽象类(abstract class)与接口(interface)的区别
  13. 高效测试用例组织算法pairwise之Python实现
  14. 都2019年了,还问GET和POST的区别
  15. 对比剖析Swarm Kubernetes Marathon编排引擎
  16. 2.8 break和continue
  17. linux(Redhat7)安装Apache
  18. 2. Spring Boot项目启动原理初探
  19. 数据库行转列、列转行,pivot透视多列
  20. 动态LINQ(Lambda表达式)

热门文章

  1. ssm框架之springMVC拦截器
  2. 前端防止xxs注入
  3. android studio生成aar包
  4. Spine学习七 - spine动画资源+ Unity Mecanim动画系统
  5. IntelliJ IDEA远程Debug Linux的Java程序,找问题不要只会看日志了
  6. Java 中基本数据类型的变量的转换规则
  7. P1306 斐波那契公约数(ksm+结论)
  8. HDU - 4548-美素数 (欧拉素数筛+打表)
  9. C# 发送邮件通知
  10. Spring Boot 集成阿里云 OSS 进行文件存储