Skip to content

Latest commit

 

History

History
123 lines (116 loc) · 4.44 KB

1728.md

File metadata and controls

123 lines (116 loc) · 4.44 KB

1728. Cat and Mouse II

Solution 1

class Node(object):
    def __init__(self, mx, my, cx, cy, m_round):
        self.mx = mx
        self.my = my
        self.cx = cx
        self.cy = cy
        self.m_round = m_round
        self.win_state = None
        self.out_d = 0
        self.g = set()

class Solution(object):
    def canMouseWin(self, grid, catJump, mouseJump):
        """
        :type grid: List[str]
        :type catJump: int
        :type mouseJump: int
        :rtype: bool
        """
        m = len(grid)
        n = len(grid[0])
        for i in range(m):
            for j in range(n):
                if grid[i][j] == '#':
                    continue
                if grid[i][j] == 'C':
                    cx = i
                    cy = j
                elif grid[i][j] == 'M':
                    mx = i
                    my = j
                elif grid[i][j] == 'F':
                    fx = i
                    fy = j
        
        node_dict = {}
        for x1 in range(m):
            for y1 in range(n):
                if grid[x1][y1] == '#':
                    continue
                for x2 in range(m):
                    for y2 in range(n):
                        if grid[x2][y2] == '#':
                            continue
                        if x1 == fx and y1 == fy and x2 == fx and y2 == fy:
                            continue
                        if x1 == fx and y1 == fy:
                            node_dict[(x1, y1, x2, y2, 0)] = Node(x1, y1, x2, y2, 0)
                        elif x2 == fx and y2 == fy:
                            node_dict[(x1, y1, x2, y2, 1)] = Node(x1, y1, x2, y2, 1)
                        elif x1 == x2 and y1 == y2:
                            node_dict[(x1, y1, x2, y2, 1)] = Node(x1, y1, x2, y2, 1)
                        else:
                            node_dict[(x1, y1, x2, y2, 0)] = Node(x1, y1, x2, y2, 0)
                            node_dict[(x1, y1, x2, y2, 1)] = Node(x1, y1, x2, y2, 1)

        dx = [1, 0, -1, 0]
        dy = [0, 1, 0, -1]
        for node in node_dict.values():
            if node.mx == fx and node.my == fy:
                continue
            if node.cx == fx and node.cy == fy:
                continue
            if node.mx == node.cx and node.my == node.cy:
                continue
            if node.m_round == 1:
                step_range = mouseJump
                nowx, nowy = node.mx, node.my
            else:
                step_range = catJump
                nowx, nowy = node.cx, node.cy
            for index in range(4):
                for l in range(1, step_range + 1):
                    x = dx[index] * l + nowx
                    y = dy[index] * l + nowy
                    if x < 0 or x == m or y < 0 or y == n or grid[x][y] == '#':
                        break
                    if node.m_round == 1:
                        if x == node.cx and y == node.cy:
                            continue
                        next_node = node_dict[(x, y, node.cx, node.cy, 0)]
                    else:
                        next_node = node_dict[(node.mx, node.my, x, y, 1)]
                    node.out_d += 1
                    next_node.g.add(node)
            node.out_d += 1
            node_dict[(node.mx, node.my, node.cx, node.cy, 1 - node.m_round)].g.add(node)

        q = []
        for node in node_dict.values():
            if ((node.mx == fx and node.my == fy) or
                (node.cx == fx and node.cy == fy) or
                (node.mx == node.cx and node.my == node.cy)):
                node.win_state = False
                q.append(node)
        l = 0
        r = len(q)
        round = 0
        while l < r and round < 1000:
            round += 1
            for node in q[l : r]:
                if not node.win_state:
                    for pre_node in node.g:
                        if pre_node.win_state is None:
                            pre_node.win_state = True
                            q.append(pre_node)
                else:
                    for pre_node in node.g:
                        pre_node.out_d -= 1
                        if pre_node.out_d == 0:
                            pre_node.win_state = False
                            q.append(pre_node)
            l, r = r, len(q)

        if node_dict[(mx, my, cx, cy, 1)].win_state:
            return True 
        return False