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:
3 <= graph.length <= 50- It is guaranteed that
graph[1]is non-empty. - It is guaranteed that
graph[2]contains a non-zero element.
参考_Kevin00的做法;
class Solution {
public:
int catMouseGame(vector<vector<int>>& graph)
{
winner = vector<vector<vector<PLAYER_FLAG>>>(55 , vector<vector<PLAYER_FLAG>>(55 , vector<PLAYER_FLAG>(3 , NO_PLAYER))) ;
degree = vector<vector<vector<int>>>(55 , vector<vector<int>>(55 , vector<int>(3 , 0))) ;
V = graph.size() ;
initSearch(graph) ;
return memSearch(graph) ;
}
enum PLAYER_FLAG
{
NO_PLAYER , MOUSE , CAT
};
struct State
{
int mouse_pos ;
int cat_pos ;
int now_player ;
int winner_player ;
State(int mp , int cp , int nowp , int winp):mouse_pos(mp) , cat_pos(cp) , now_player(nowp) , winner_player(winp)
{}
};
vector<vector<vector<PLAYER_FLAG>>> winner; //第三维指的是当前轮到谁出发,1是老鼠,2是猫
vector<vector<vector<int>>> degree ;
queue<State> q ;
int V ;
void initSearch(vector<vector<int>>& edge)
{
for(int v = 0 ; v < V ; ++v)
{
for(int now_player = MOUSE ; now_player <= CAT ; ++now_player)
{
winner[0][v][now_player] = MOUSE ;
winner[v][v][now_player] = CAT ;
q.emplace(0 , v , now_player , MOUSE) ;
q.emplace(v , v , now_player , CAT) ;
}
}
for(int mp = 0 ; mp < V ; ++mp)
for(int cp = 0 ; cp < V ; ++cp)
{
degree[mp][cp][MOUSE] = edge[mp].size() ;
degree[mp][cp][CAT] = edge[cp].size() ;
for(auto dest : edge[cp])
{
if(dest == 0)
{
degree[mp][cp][CAT]-- ;
break ;
}
}
}
}
int memSearch(vector<vector<int>>& edge)
{
while(!q.empty())
{
State now_state = q.front() ;
q.pop() ;
int mp = now_state.mouse_pos , cp = now_state.cat_pos , nowp = now_state.now_player , winp = now_state.winner_player ;
if(nowp == CAT)
{
int prev_p = MOUSE ;
for(int i = 0 ; i < edge[mp].size() ; ++i)
{
int prev_mp = edge[mp][i] ;
if(winner[prev_mp][cp][MOUSE] != NO_PLAYER) continue ;
if(winp == MOUSE)
{
winner[prev_mp][cp][MOUSE] = MOUSE ;
q.emplace(prev_mp , cp , MOUSE , MOUSE) ;
}
else
{
degree[prev_mp][cp][MOUSE]-- ;
if(degree[prev_mp][cp][MOUSE] == 0)
{
winner[prev_mp][cp][MOUSE] = CAT ;
q.emplace(prev_mp , cp , MOUSE , CAT) ;
}
}
}
}
else
{
int prev_p = CAT ;
for(int i = 0 ; i < edge[cp].size() ; ++i)
{
int prev_cp = edge[cp][i] ;
if(prev_cp == 0 || winner[mp][prev_cp][CAT] != NO_PLAYER) continue ;
if(winp == CAT)
{
winner[mp][prev_cp][CAT] = CAT ;
q.emplace(mp , prev_cp , CAT , CAT) ;
}
else
{
degree[mp][prev_cp][CAT]-- ;
if(degree[mp][prev_cp][CAT] == 0)
{
winner[mp][prev_cp][CAT] = MOUSE ;
q.emplace( mp , prev_cp , CAT , MOUSE) ;
}
}
}
}
}
return winner[1][2][MOUSE] ;
}
};
本文介绍了一种基于图论的策略游戏——猫鼠游戏,玩家分别扮演猫和鼠,在无向图上进行回合制博弈。游戏目标是鼠到达洞穴或避免被猫捕获。文章详细解释了游戏规则,提供了实现算法,并通过示例展示了游戏过程。

1575

被折叠的 条评论
为什么被折叠?



