LeetCode #913 Cat and Mouse 貓和老鼠 913 Cat and Mouse 貓和老鼠

913 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.

The mouse starts at node 1 and goes first, the 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 three 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 (i.e., 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 mouse wins the game,
2 if the cat wins the game, or
0 if the game is a draw.

Example:

Example 1:

Input: graph = [[2,5],[3],[0,4,5],[1,4,5],[2,3],[0,2,3]]
Output: 0

Example 2:

Input: graph = [[1,3],[0],[3],[0,2]]
Output: 1

Constraints:

3 <= graph.length <= 50
1 <= graph[i].length < graph.length
0 <= graph[i][j] < graph.length
graph[i][j] != i
graph[i] is unique.
The mouse and the cat can always move.

題目描述:
兩個玩家分別扮演貓(Cat)和老鼠(Mouse)在無向圖上進行遊戲,他們輪流行動。

該圖按下述規則給出:graph[a] 是所有結點 b 的列表,使得 ab 是圖的一條邊。

老鼠從結點 1 開始並率先出發,貓從結點 2 開始且隨後出發,在結點 0 處有一個洞。

在每個玩家的回合中,他們必須沿着與他們所在位置相吻合的圖的一條邊移動。例如,如果老鼠位於結點 1,那麼它只能移動到 graph[1] 中的(任何)結點去。

此外,貓無法移動到洞(結點 0)裏。

然後,遊戲在出現以下三種情形之一時結束:

如果貓和老鼠佔據相同的結點,貓獲勝。
如果老鼠躲入洞裏,老鼠獲勝。
如果某一位置重複出現(即,玩家們的位置和移動順序都與上一個回合相同),遊戲平局。
給定 graph,並假設兩個玩家都以最佳狀態參與遊戲,如果老鼠獲勝,則返回 1;如果貓獲勝,則返回 2;如果平局,則返回 0。

示例 :

輸入:[[2,5],[3],[0,4,5],[1,4,5],[2,3],[0,2,3]]
輸出:0
解釋:

4---3---1
|   |
2---5
 \ /
  0

提示:

3 <= graph.length <= 200
保證 graph[1] 非空。
保證 graph[2] 包含非零元素。

思路:

動態規劃
記錄每一步的狀態, dp[t][x][y] 表示走了 t 步, 老鼠在 x 位置, 貓在 y 位置, 當前的勝利狀態
dp[t][x][y] = 0 表示平局, dp[t][x][y] = 1 表示老鼠獲勝, dp[t][x][y] = 2 表示貓獲勝
dp 最多隻需要 2 * n 步, 因爲貓和老鼠每個分別可以走 n 步, 2 * n 步之後必然發生重複, 超過範圍必然是平局, 返回 0
如果當前 x == y, 即老鼠和貓相遇, 那麼是貓獲勝
如果當前 x == 0, 即老鼠回洞, 則是由老鼠獲勝
如果當前 dp[t][x][y] != -1, 說明已經搜索過這種情況, 不需要搜索, 直接返回 dp[t][x][y]
否則按照 t 的奇偶性進入選擇
如果 t 爲偶數, 當前行動的是老鼠, 用 BFS 的方式搜索所有老鼠當前位置能去的點 next, 如果 next 爲 1 則老鼠必勝, 如果 next == 0 說明下一步還是平局, 否則如果怎麼走都是貓獲勝就是貓獲勝
t 爲奇數情況類似
注意貓不能進入洞中
時間複雜度爲 O(n ^ 3), 空間複雜度爲 O(n ^ 2)

代碼:
C++:

class Solution 
{
public:
    int catMouseGame(vector<vector<int>>& graph) 
    {
        int n = graph.size();
        vector<vector<vector<int>>> dp(n << 1, vector<vector<int>>(n, vector<int>(n, -1)));
        return helper(graph, 0, 1, 2, dp);
    }
private:
    int helper(vector<vector<int>>& graph, int t, int x, int y, vector<vector<vector<int>>>& dp) 
    {
        if (t == dp.size()) return 0;
        if (x == y) return dp[t][x][y] = 2;
        if (!x) return dp[t][x][y] = 1;
        if (dp[t][x][y] != -1) return dp[t][x][y];
        if (!(t & 1)) 
        {
            bool cat = true;
            for (int i = 0; i < graph[x].size(); i++) 
            {
                int next = helper(graph, t + 1, graph[x][i], y, dp);
                if (next == 1) return dp[t][x][y] = 1;
                else if (next != 2) cat = false;
            }
            if (cat) return dp[t][x][y] = 2;
        } 
        else 
        {
            bool mouse = true;
            for (int i = 0; i < graph[y].size(); i++) 
            {
                if (graph[y][i] == 0) continue;
                int next = helper(graph, t + 1, x, graph[y][i], dp);
                if (next == 2) return dp[t][x][y] = 2;
                else if (next != 1) mouse = false;
            }
            if (mouse) return dp[t][x][y] = 1;
        }
        return dp[t][x][y] = 0;
    }
};

Java:

class Solution {
    public int catMouseGame(int[][] graph) {
        int n = graph.length, dp[][][] = new int[n << 1][n][n];
        for (int i = 0; i < (n << 1); i++) for (int j = 0; j < n; j++) Arrays.fill(dp[i][j], -1);
        return helper(graph, dp, 0, 1, 2);
    }
    
    private int helper(int[][] graph, int[][][] dp, int t, int x, int y) {
        if (t == dp.length) return 0;
        if (x == y) return dp[t][x][y] = 2;
        if (x == 0) return dp[t][x][y] = 1;
        if (dp[t][x][y] != -1) return dp[t][x][y];
        if ((t & 1) != 0) {
            boolean mouse = true;
            for (int i = 0; i < graph[y].length; i++) {
                if (graph[y][i] == 0) continue;
                int next = helper(graph, dp, t + 1, x, graph[y][i]);
                if (next == 2) return dp[t][x][y] = 2;
                else if (next != 1) mouse = false;
            }
            if (mouse) return dp[t][x][y] = 1;
        } else {
            boolean cat = true;
            for (int i = 0; i < graph[x].length; i++) {
                int next = helper(graph, dp, t + 1, graph[x][i], y);
                if (next == 1) return dp[t][x][y] = 1;
                else if (next != 2) cat = false;
            }
            if (cat) return dp[t][x][y] = 2;
        }
        return dp[t][x][y] = 0;
    }
}

Python:

class Solution:
    def catMouseGame(self, graph: List[List[int]]) -> int:
        @lru_cache(None)
        def helper(t: int, x: int, y: int) -> int:
            if t == (len(graph) << 1): 
                return 0
            if x == y:
                return 2
            if x == 0:
                return 1
            if t & 1:
                if any(helper(t + 1, x, i) == 2 for i in graph[y] if i):  
                    return 2
                if any(helper(t + 1, x, i) == 0 for i in graph[y] if i):  
                    return 0
                return 1
            else:
                if any(helper(t + 1, i, y) == 1 for i in graph[x]):       
                    return 1
                if any(helper(t + 1, i, y) == 0 for i in graph[x]):    
                    return 0
                return 2
        return helper(0, 1, 2)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章