913. Cat and Mouse

解法

一开始想用alpha-beta啥的,但是超时了
mouse, cat, player代表游戏的每一个状态,把游戏运行过程想像成这些状态连成的有向图。
其中有的状态的马上就被判断出结果:

  1. (0,cat,player):这种情况一定是老鼠赢,着色为MOUSE
  2. (i,i,player):这种情况一定是猫赢,着色为CAT

还有些状态能被间接着色:

  1. (mouse, cat, player)的后继节点只要有一个着色为player时,它就能被着色为player
  2. (mouse, cat, player)的后继节点全都被着色为另一个player时,它就会被着色为另一个player

所有的节点都着色完之后(不管是直接还是间接),剩下的节点都是平局节点。最后我们只关心(1,2,MOUSE)的着色是什么。

算法这样进行:

  1. 先统计每个状态的子节点的数量,记作d[m,c,p],我们用它来代表未被着色为对家的子节点数量
  2. 然后对所有能直接着色的节点着色,把它们放到队列里。
  3. 对于队列里的每个已着色为color的节点,找到它们的每个父节点m1,c1,p1,如果它还没着色:
    • 如果color==p1,那么父节点可以直接被着色为color,然后我们把这个节点加入队列
    • 否则,我们把未被着色为对家的子节点数量减一:d[m1,c1,p1]-=1,如果减完之后未遍历节点为0了,说明这个父节点的所有子节点都被着色为了另一个player,那么它当然也只能被着色为另一个player,我们着色并将此节点添加到队列
  4. 最后输出1,2,MOUSE的状态即可

特别注意猫不能走0的设定!!!!

class Solution(object):
    def catMouseGame(self, graph):
        """
        :type graph: List[List[int]]
        :rtype: int
        """
        from collections import defaultdict
        DRAW, MOUSE, CAT = 0,1,2
        color = defaultdict(int)
        queue = []
        n = len(graph)
        for i in xrange(n):
            for player in xrange(1,3):
                color[(0, i, player)] = MOUSE
                queue.append((0, i, player, MOUSE))
                if i>0:
                    color[(i, i, player)] = CAT
                    queue.append((i,i,player,CAT))
        d = {}
        for m,c in itertools.product(xrange(n), repeat=2):
            d[(m,c,MOUSE)] = len(graph[m])
            d[(m,c,CAT)] = len(graph[c])-(0 in graph[c])

        def parents(m,c,p):
            if p==MOUSE:
                for c0 in graph[c]:
                    if c0:
                        yield m,c0,3-p
            else:
                for m0 in graph[m]:
                    yield m0,c,3-p

        while len(queue):
            mouse,cat ,player, col = queue.pop(0)
            for m,c,p in parents(mouse, cat, player):
                if color[(m,c,p)]==DRAW:
                    if p==col:
                        color[(m,c,p)] = col
                        queue.append((m,c,p,col))
                    else:
                        d[(m,c,p)] -= 1
                        if d[(m,c,p)] == 0:
                            color[(m,c,p)] = 3-p
                            queue.append((m,c,p,3-p))
        return color[(1,2,1)]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值