https://vjudge.net/problem/HDU-3980
题意
一串长度为n的柱子,每个人只能给连续的珠子涂色,涂过的不能再涂,不能涂的人就输了,问最后谁获胜。
分析
第一个人先涂m个,就把环变成链了,先手就变为后手。现在考虑长度为N-M的链上的游戏,用子状态来推出当前状态,一个问题的结果是其子问题的结果的亦或,然后使用记忆化推出sg,就知道谁赢了。
#include<iostream> #include<cmath> #include<cstring> #include<queue> #include<vector> #include<cstdio> #include<algorithm> #include<map> #include<set> #define rep(i,e) for(int i=0;i<(e);i++) #define rep1(i,e) for(int i=1;i<=(e);i++) #define repx(i,x,e) for(int i=(x);i<=(e);i++) #define X first #define Y second #define PB push_back #define MP make_pair #define mset(var,val) memset(var,val,sizeof(var)) #define scd(a) scanf("%d",&a) #define scdd(a,b) scanf("%d%d",&a,&b) #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c) #define pd(a) printf("%d ",a) #define scl(a) scanf("%lld",&a) #define scll(a,b) scanf("%lld%lld",&a,&b) #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c) #define IOS ios::sync_with_stdio(false);cin.tie(0) using namespace std; typedef long long ll; template <class T> void test(T a){cout<<a<<endl;} template <class T,class T2> void test(T a,T2 b){cout<<a<<" "<<b<<endl;} template <class T,class T2,class T3> void test(T a,T2 b,T3 c){cout<<a<<" "<<b<<" "<<c<<endl;} const int inf = 0x3f3f3f3f; const ll INF = 0x3f3f3f3f3f3f3f3fll; const ll mod = 200907; int T; void testcase(){ printf("Case #%d: ",++T); } const int MAXN = 1024; const int MAXM = 30; int sg[MAXN],N,M; int SG(int n){ if(sg[n]!=-1) return sg[n]; if(n<M) return sg[n]=0; int vis[MAXN]; mset(vis,0); for(int i=0;i<=n-M;i++){ vis[SG(n-M-i)^SG(i)]=1; } for(int i=0;;i++) if(!vis[i]) return sg[n]=i; } int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif // LOCAL int t; T=0; scd(t); while(t--){ scdd(N,M); mset(sg,-1); testcase(); if(N<M){ puts("abcdxyzk"); continue; } if(SG(N-M)) puts("abcdxyzk"); else puts("aekdycoin"); } return 0; }