【LeetCode】913. Cat and Mouse 解题报告(Python)
作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址:https://leetcode.com/problems/cat-and-mouse/description/
题目描述
A game on an undirected
graph is played by two players, Mouse and Cat, who alternate turns.
The graph is given as follows: graph[a]
is a list of all nodes b
such that ab
is an edge of the graph.
Mouse starts at node 1 and goes first, Cat starts at node 2 and goes second, and there is a Hole at node 0.
During each player’s turn, they must travel along one edge of the graph that meets where they are. For example, if the Mouse is at node 1
, it must
travel to any node in graph[1]
.
Additionally, it is not allowed for the Cat to travel to the Hole (node 0.)
Then, the game can end in 3 ways:
- If ever the Cat occupies the same node as the Mouse, the Cat wins.
- If ever the Mouse reaches the Hole, the Mouse wins.
- If ever a position is repeated (ie. the players are in the same position as a previous turn, and it is the same player’s turn to move), the game is a draw.
Given a graph
, and assuming both players play optimally, return 1
if the game is won by Mouse, 2
if the game is won by Cat, and 0
if the game is a draw.
Example 1:
Input: [[2,5],[3],[0,4,5],[1,4,5],[2,3],[0,2,3]]
Output: 0
Explanation:
4---3---1
| |
2---5
\ /
0
Note:
- 3 <= graph.length <= 50
- It is guaranteed that graph[1] is non-empty.
- It is guaranteed that graph[2] contains a non-zero element.
题目大意
猫鼠游戏。
有一张无向图,包含最多50个结点。有两个玩家(Mouse和Cat)在图上,Mouse的起始位置是1,Cat的起始位置是2,0处有一个洞,Cat不能移动到0。Mouse和Cat在图上轮流移动,每次必须移动到与当前结点相邻的一个结点。
游戏有三种结束的可能:
- Cat和Mouse进入同一结点,则Cat胜利
- Mouse进入0结点,则Mouse胜利
- Cat和Mouse的位置和回合发生了重复,则平局
问:如果Cat和Mouse都以最优策略行动,最后的结果是什么?
解题方法
这个题实在太难了,我只能参考别人的做法了。正确的做法应该是BFS,而且是已知结果倒着求过程的BFS。
设计节点状态是(m,c,turn),用color[m][c][turn]来记忆该状态的输赢情况.
首先我们将所有已知的确定状态加入一个队列.已知状态包括(0,c,turn)肯定是老鼠赢,(x,x,turn)且x!=0肯定是猫赢。我们尝试用BFS的思路,将这些已知状态向外扩展开去.
扩展的思路是:从队列中取出队首节点状态(m,c,t),找到它的所有邻接的parent的状态(m2,c2,t2).这里的父子关系是指,(m2,c2,t2)通过t2轮(老鼠或猫)的操作,能得到(m,c,t).我们发现,如果(m,c,t)是老鼠赢而且t2是老鼠轮,那么这个(m2,c2,t2)一定也是老鼠赢.同理,猫赢的状态也类似.于是,我们找到了一种向外扩展的方法.
向外扩展的第二个思路是:对于(m2,c2,t2),我们再去查询它的所有children(必定是对手轮)是否都已经标注了赢的状态.如果都是赢的状态,那么说明(m2,c2,t2)无路可走,只能标记为输的状态.特别注意的是,第一条规则通过child找parent,和第二条规则通过parent找child的算法细节是不一样的,一定要小心.
这样我们通过BFS不断加入新的探明输赢的节点.直到队列为空,依然没有探明输赢的节点状态,就是平局的意思!
最后输出(1, 2, MOUSE)的颜色。没有被染过色说明是平局。
时间复杂度是O(VE),空间复杂度是O(V).
class Solution(object):
def catMouseGame(self, graph):
"""
:type graph: List[List[int]]
:rtype: int
"""
N = len(graph)
MOUSE, CAT = 1, 2
# mouse, cat, turn
color = [[[0] * 3 for i in range(N)] for j in range(N)]
q = collections.deque()
for i in range(1, N):
for t in range(1, 3):
color[0][i][t] = 1
q.append((0, i, t))
color[i][i][t] = 2
q.append((i, i, t))
while q:
curStatus = q.popleft()
cat, mouse, turn = curStatus
for preStatus in self.findAllPrevStatus(graph, curStatus):
preCat, preMouse, preTurn = preStatus
if color[preCat][preMouse][preTurn] != 0:
continue
if color[cat][mouse][turn] == 3 - turn:
color[preCat][preMouse][preTurn] = preTurn
q.append(preStatus)
elif self.allNeighboursWin(color, graph, preStatus):
color[preCat][preMouse][preTurn] = 3 - preTurn
q.append(preStatus)
return color[1][2][1]
def findAllPrevStatus(self, graph, curStatus):
ret = []
mouse, cat, turn = curStatus
if turn == 1:
for preCat in graph[cat]:
if preCat == 0:
continue
ret.append((mouse, preCat, 2))
else:
for preMouse in graph[mouse]:
ret.append((preMouse, cat, 1))
return ret
def allNeighboursWin(self, color, graph, status):
mouse, cat, turn = status
if turn == 1:
for nextMouse in graph[mouse]:
if color[nextMouse][cat][2] != 2:
return False
elif turn == 2:
for nextCat in graph[cat]:
if nextCat == 0:
continue
if color[mouse][nextCat][1] != 1:
return False
return True
参考资料
https://zhanghuimeng.github.io/post/leetcode-913-cat-and-mouse/
https://github.com/wisdompeak/LeetCode/tree/master/BFS/913.Cat-and-Mouse
日期
2018 年 10 月 24 日 —— 程序员节被严重炒作了啊
【LeetCode】913. Cat and Mouse 解题报告(Python)的更多相关文章
- [LeetCode] 913. Cat and Mouse 猫和老鼠
A game on an undirected graph is played by two players, Mouse and Cat, who alternate turns. The grap ...
- 【LeetCode】62. Unique Paths 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/unique-pa ...
- 【LeetCode】376. Wiggle Subsequence 解题报告(Python)
[LeetCode]376. Wiggle Subsequence 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.c ...
- 【LeetCode】649. Dota2 Senate 解题报告(Python)
[LeetCode]649. Dota2 Senate 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地 ...
- 【LeetCode】911. Online Election 解题报告(Python)
[LeetCode]911. Online Election 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ ...
- 【LeetCode】886. Possible Bipartition 解题报告(Python)
[LeetCode]886. Possible Bipartition 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu ...
- 【LeetCode】36. Valid Sudoku 解题报告(Python)
[LeetCode]36. Valid Sudoku 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址 ...
- 【LeetCode】870. Advantage Shuffle 解题报告(Python)
[LeetCode]870. Advantage Shuffle 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn ...
- 【LeetCode】593. Valid Square 解题报告(Python)
[LeetCode]593. Valid Square 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地 ...
随机推荐
- 【Python小试】计算蛋白序列中指定氨基酸所占的比例
编码 from __future__ import division def get_aa_percentage(protein, aa_list=['A','I','L','M','F','W',' ...
- kubernetes部署kube-scheduler服务
同样的分非认证授权和认证授权: 非认证授权: cat > /lib/systemd/system/kube-scheduler.service <<EOF [Unit] Descri ...
- Phoenix二级索引
Phoenix Hbase适合存储大量的对关系运算要求低的NOSQL数据,受Hbase 设计上的限制不能直接使用原生的API执行在关系数据库中普遍使用的条件判断和聚合等操作.Hbase很优秀,一些团队 ...
- 大数据学习day26----hive01----1hive的简介 2 hive的安装(hive的两种连接方式,后台启动,标准输出,错误输出)3. 数据库的基本操作 4. 建表(内部表和外部表的创建以及应用场景,数据导入,学生、分数sql练习)5.分区表 6加载数据的方式
1. hive的简介(具体见文档) Hive是分析处理结构化数据的工具 本质:将hive sql转化成MapReduce程序或者spark程序 Hive处理的数据一般存储在HDFS上,其分析数据底 ...
- Shell学习(八)——dd命令
一.dd命令的解释 dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 注意:指定数字的地方若以下列字符结尾,则乘以相应的数字:b=512:c=1:k=1024:w=2 参数注释: 1. ...
- 【Go】【Basic】MacOS上搭建GO开发环境
1. GO下载 1.1. 下载地址:https://www.golangtc.com/download (需要科学上网) 1.1.1. PKG安装: 下载这个包:go1.9.2.darwin-amd6 ...
- 在隐藏导航栏的控制器中,调用UIIMagePickerController,出现导航栏变透明的问题
在隐藏导航栏的控制器中,调用UIIMagePickerController,出现导航栏变透明的问题 解决办法 #pragma mark - UIImagePickerController Delega ...
- 删除数据库时报错 ERROR 1010 (HY000): Error dropping database (can't rmdir './cart', errno: 39)
这是因为在数据目录下有表相关的数据(不是表),此时应该进入存放表的目录下删除与表相关的数据,一般数据存放目录默认为/var/lib/mysql,cd到目录下 执行命令:cd /var/lib/mysq ...
- sql优化的8种方式
1.设置索引. MySQL索引操作:给表列创建索引: 建表时创建索引: create table t(id int,name varchar(20),index idx_name (name)); 给 ...
- 【Java 基础】 instanceof和isInstance区别详解
obj instanceof class 也就是说这个对象是不是这种类型, 1.一个对象是本身类的一个对象 2.一个对象是本身类父类(父类的父类)和接口(接口的接口)的一个对象 3.所有对象都是Obj ...