zoukankan      html  css  js  c++  java
  • 913. Cat and Mouse

    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:

    1. 3 <= graph.length <= 50
    2. It is guaranteed that graph[1] is non-empty.
    3. It is guaranteed that graph[2] contains a non-zero element.
    class Solution:
        def catMouseGame(self, graph):
            """
            :type graph: List[List[int]]
            :rtype: int
            """
            n = len(graph)
            color = [[[0]*3 for i in range(n)] for j in range(n)]
            #color中分别代表mouse的位置,cat的位置,mouse或cat的turn,1代表mouse,2代表cat
            q = []
            for i in range(1,n): #初始状态标记
                for t in range(1,3):
                    color[0][i][t] = 1 #对于这种状态,肯定是mouse win
                    q.append((0,i,t))
                    color[i][i][t] = 2 #对于这种状态,肯定是cat win
                    q.append((i,i,t))
            while len(q):
                curstatus = q.pop(0)
                mouse,cat,turn = curstatus
                for prestatus in self.findallprestatus(graph,curstatus):
                    premouse,precat,preturn = prestatus
                    if color[premouse][precat][preturn] !=0: #已经被标记
                        continue
                    if color[mouse][cat][turn]==3-turn:
                    #从队列中取出队首节点状态(m,c,t),找到它的所有邻接的parent的状态(m2,c2,t2).
                    #这里的父子关系是指,(m2,c2,t2)通过t2轮(老鼠或猫)的操作,能得到(m,c,t).
                    #我们发现,如果(m,c,t)是老鼠赢而且t2是老鼠轮,那么这个(m2,c2,t2)一定也是老鼠赢.同理,猫赢的状态也类似.
                        color[premouse][precat][preturn] = preturn
                        q.append(prestatus)
                    elif self.allneighbourswin(color,graph,prestatus):
                    #对于(m2, c2, t2),我们再去查询它的所有children(必定是对手轮)是否都已经标注了赢的状态.如果都是赢的状态,那么说明(m2, c2, t2)
                    #无路可走,只能标记为输的状态.特别注意的是,第一条规则通过child找parent,和第二条规则通过parent找child的算法细节是不一样的,一定要小心.
                        color[premouse][precat][preturn] = 3-preturn
                        q.append(prestatus)
            return color[1][2][1]
    
        def findallprestatus(self,graph,curstatus):
            res = []
            mouse,cat,turn = curstatus
            if turn==1: #前一步该cat走
                for precat in graph[cat]:#只可能来自与其相邻的点
                    if precat==0:#猫不可以进洞
                        continue
                    res.append((mouse,precat,2))
            else: #前一步该mouse走
                for premouse in graph[mouse]:
                    res.append((premouse,cat,1))
            return res
    
        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://blog.csdn.net/fuxuemingzhu/article/details/83350880

  • 相关阅读:
    mysql中cast() 和convert()的用法讲解
    li内有span需要右浮的问题
    svn检出项目
    vue中的 ref 和 $refs
    for in 循环 和for循环 for of循环
    setInterval()、clearInterval()、setTimeout()和clearTimeout() js计数器方法(还有第三个参数)
    利用history.pushState()实现页面无刷新更新
    函数isNaN() parseFloat() parseInt() Math对象
    一个关于margin-top的问题
    vue 父子组件之间传参
  • 原文地址:https://www.cnblogs.com/bernieloveslife/p/10238936.html
Copyright © 2011-2022 走看看