【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版】

Python练习题 017:三支乒乓球队出赛名单的更多相关文章

  1. Python练习题 028:求3*3矩阵对角线数字之和

    [Python练习题 028] 求一个3*3矩阵对角线元素之和 ----------------------------------------------------- 这题解倒是解出来了,但总觉得 ...

  2. Python练习题 027:对10个数字进行排序

    [Python练习题 027] 对10个数字进行排序 --------------------------------------------- 这题没什么好说的,用 str.split(' ') 获 ...

  3. Python练习题 026:求100以内的素数

    [Python练习题 026] 求100以内的素数. ------------------------------------------------- 奇怪,求解素数的题,之前不是做过了吗?难道是想 ...

  4. Python练习题 025:判断回文数

    [Python练习题 025] 一个5位数,判断它是不是回文数.即12321是回文数,个位与万位相同,十位与千位相同. ---------------------------------------- ...

  5. Python练习题 024:求位数及逆序打印

    [Python练习题 024] 给一个不多于5位的正整数,要求:一.求它是几位数,二.逆序打印出各位数字. ---------------------------------------------- ...

  6. Python练习题 004:判断某日期是该年的第几天

    [Python练习题 004]输入某年某月某日,判断这一天是这一年的第几天? ---------------------------------------------- 这题竟然写了 28 行代码! ...

  7. Python练习题-1.使用匿名函数对1~1000求和,代码力求简洁。

    Python 练习 标签(空格分隔): Python Python练习题 Python知识点 一.使用匿名函数对1~1000求和,代码力求简洁. 答案: In [1]: from functools ...

  8. PYTHON练习题 二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数。

    Python 练习 标签: Python Python练习题 Python知识点 二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数,如果大于预设的 ...

  9. python 基础 2.8 python练习题

    python 练习题:   #/usr/bin/python #coding=utf-8 #@Time   :2017/10/26 9:38 #@Auther :liuzhenchuan #@File ...

随机推荐

  1. 状态压缩动态规划(状压DP)详解

    0 引子 不要999,也不要888,只要288,只要288,状压DP带回家.你买不了上当,买不了欺骗.它可以当搜索,也可以卡常数,还可以装B,方式多样,随心搭配,自由多变,一定符合你的口味! 在计算机 ...

  2. 正则表达式断言精讲 Java语法实现

    目录 断言 1.2.3.1 情景导入 什么是断言 断言的语法规则 零宽断言为什么叫零宽断言 零宽 前行 负向 断言DEMO 断言的基础应用和实际用处 验证不包含 验证开头包含 验证开头包含且匹配到的数 ...

  3. solrcloud集群版的搭建

    说在前面的话 之前我们了解到了solr的搭建,我们的solr是搭建在tomcat上面的,由于tomcat并不能过多的承受访问的压力,因此就带来了solrcloud的时代.也就是solr集群. 本次配置 ...

  4. laravel中elastisearch安装和测试运行是否成功(注意是windows下的操作)

    1.去elasticsearch官网下载,如果太慢可以在我上一个随笔看下载地址 2.下载完解压缩,在cmd中找到到elasticsearch的bin目录下执行.\elasticsearch.bat - ...

  5. Python基础(闭包函数、装饰器、模块和包)

    闭包函数 格式: def 函数名1(): def 函数名2(): 变量 = 值 return 变量 return 函数名2 func = 函数名1() key = func()

  6. adb 打开手机端口进行无线模式调试

    打开手机端口 让手机在指定的端口可以接收到TCP/IP连接. 确保手机开启了usb调试 用usb线把手机和电脑连接起来 执行命令:adb tcpip 5555 执行成功后就可以把usb线拔掉了,端口可 ...

  7. add forward

    adb forward tcp:34999 localabstract:Unity-com.kingsgroup.rob adb forward --list adb forward --remove ...

  8. Spring security OAuth2.0认证授权学习第一天(基础概念-认证授权会话)

    这段时间没有学习,可能是因为最近工作比较忙,每天回来都晚上11点多了,但是还是要学习的,进过和我的领导确认,在当前公司的技术架构方面,将持续使用Spring security,暂不做Shiro的考虑, ...

  9. docker打包项目

    nginx镜像制作实战 docker容器的主业 docker理念里,容器启动时,应当为它指定主业是什么,如nginx容器主业就是nginx代理服务,tomcat容器就是web服务等等 1.容器创建时, ...

  10. Linux:crond(crontab)定时任务

    一..定义 Crond 是linux系统中用来定期执行命令或指定程序任务的一种服务或者软件.一般在安装完系统时,crond会默认存在. crond默认每分钟会检查系统中是否有需要执行的定时任务.如果有 ...