题解 | 田忌赛马
田忌赛马
https://www.nowcoder.com/practice/49d799f65a0749588e9cd7e6135a4a9a
import sys
from itertools import permutations
# 生成可迭代对象的所有可能的排列(Permutations)
# permutations(iterable, r=None)
line1 = input().split()
line2 = input().split()
# v1,v2,v3 = map(int,line1)
# a1,a2,a3 = map(int,line2)
v = list(map(int,line1)) # 齐王马的出场顺序
a = list(map(int,line2)) # 田忌的马
perms = permutations(a) # 所有排列
# print(perms)
awins = False
for perm in perms:
wins = 0
for i in range(3):
if perm[i] > v[i]:
wins += 1
if wins >= 2:
awins = True
break
print("Yes" if awins else "No")
itertools.permutations 是 Python 标准库 itertools 模块中的一个非常有用的函数,用于生成可迭代对象的所有可能的排列(Permutations)。
📌 基本语法
permutations(iterable, r=None)
iterable:要进行排列的可迭代对象,比如字符串、列表等。r:可选参数,表示每个排列的长度(即取多少个元素进行排列)。如果不指定 r,默认为 len(iterable),即全排列。如果指定 r,则生成长度为 r 的所有排列。
返回值是一个迭代器,可以使用 for 循环遍历,或用 list() 转成列表。
✅ 基本用法示例
1. 生成列表的全排列
from itertools import permutations
nums = [1, 2, 3]
perms = permutations(nums)
for p in perms:
print(p)
输出:
(1, 2, 3) (1, 3, 2) (2, 1, 3) (2, 3, 1) (3, 1, 2) (3, 2, 1)
共 3! = 6 种排列。
2. 生成字符串的全排列
from itertools import permutations
s = "ABC"
perms = permutations(s)
for p in perms:
print(''.join(p))
输出:
ABC ACB BAC BCA CAB CBA
注意:
permutations返回的是元组,所以需要用''.join()把字符元组拼成字符串。
3. 生成部分排列(指定 r)
from itertools import permutations
nums = [1, 2, 3]
perms = permutations(nums, r=2) # 取2个元素的排列
for p in perms:
print(p)
输出:
(1, 2) (1, 3) (2, 1) (2, 3) (3, 1) (3, 2)
共 P(3,2) = 3×2 = 6 种排列。
⚠️ 注意事项
- 元素按位置排列,不自动去重如果原序列有重复元素,permutations 会把它们当作不同元素处理(因为它们在不同位置)。输出:看到重复了!因为两个 1 被视为不同。解决方法: 使用 set() 去重:输出:
- 返回的是迭代器,不是列表节省内存,适合大数据。但只能遍历一次,如果需要多次使用,建议转成 list。
- 排列与组合的区别permutations:顺序重要,(1,2) 和 (2,1) 是不同的。combinations:顺序无关,(1,2) 和 (2,1) 视为相同。
✅ 实际应用场景
全排列搜索 | 如田忌赛马问题,枚举所有可能的出马顺序 |
密码破解 | 生成所有可能的数字/字母排列 |
路径搜索 | 枚举访问城市的顺序(TSP 旅行商问题简化版) |
游戏策略 | 尝试所有可能的操作顺序 |
✅ 小结
| 生成全排列 |
| 生成长度为
的排列 |
| 转为列表 |
| 去除重复排列(适用于有重复元素时) |
✅ 一句话总结
itertools.permutations是一个高效生成所有可能排列的工具,适合在小规模数据上进行暴力枚举或组合搜索,是解决排列类问题的利器。
