题意: 给你一个树,之后有一些询问然后你可以在一些节点里放一枚棋子,每次可以往一个树枝边移动,谁不能移动谁输
思路: 就是我们需要打一个SG表,之后一个一次游戏的SG值是他子游戏的异或和就ok了
上代码把:
#include <stdio.h> #include <string.h> #include <algorithm> #include <vector> using namespace std; const int maxn = 1e3+10; vector<int>V[maxn]; int sg[maxn]; int dfs(int x){ if (sg[x]!=-1) return sg[x]; // 记忆化搜索 int mex[maxn];//注意这里的mex每次都有重新定义,因为他每进入一层深搜的话,那么就要一个新的mex memset(mex,0,sizeof(mex)); for(int i=0;i<V[x].size();i++) mex[dfs(V[x][i])]=1;//他的子游戏其实就是他的子节点 for(int i=0;;i++) if (!mex[i]) return sg[x]=i; } int main() { int n; while(scanf("%d",&n)!=EOF) { int t,te; for(int i = 0 ; i < n ; i++) { V[i].clear(); scanf("%d",&t); while(t--) { scanf("%d",&te); V[i].push_back(te); } } memset(sg,-1,sizeof(sg)); while(scanf("%d",&te)) { int ans = 0; if(te == 0) break; while(te--) { scanf("%d",&t); ans = ans ^ dfs(t);//得到t的sg值 } if(ans) { puts("WIN"); } else puts("LOSE"); } } }