• 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

  • 相关阅读:
    Git SSH Key 生成步骤
    IOS音频1:之采用四种方式播放音频文件(一)AudioToolbox AVFoundation OpenAL AUDIO QUEUE
    IOS网络篇1之截取本地URL请求(NSURLProtocol)
    IOS 视频直播/智能家居(一行行敲代码,从零开始)lesson:1整体架构
    iOS应用支持IPV6,就那点事儿
    App store最新审核标准公布
    iOS应用内付费(IAP)开发步骤列表
    iOS应用内支付(IAP)的那些坑
    IOS 第三方支付的使用:支付宝
    亲们,委托你们是否已忘记
  • 原文地址:https://www.cnblogs.com/bernieloveslife/p/10238936.html
Copyright © 2020-2023  润新知