这几天睡眠时间都不太够,室友晚上太会折腾了,感觉有点累,所以昨天的题解也没写,看晚上能不能补起来。
B . Marbles
题意:给定N组数(xi,yi),玩家轮流操作,每次玩家可以选择其中一组对其操作,可以把它减去一个数,或同时减去一个数,当玩家操作后出现了(0,0)则胜利。
思路:注意这里是出现(0,0)胜,而不是全都是(0,0)胜,所以我们不能简单的球sg,最后异或得到答案。
但是我们转化一下,如果玩家面对的全是(1,2) 或(2,1),则他胜利,那么我们可以以这两个状态为起点得到sg函数,就转化为了nim博弈。 当然,前提是没有xi==yi的情况。
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=210; int sg[maxn][maxn],vis[maxn]; void getsg() { rep(i,1,100) rep(j,1,100){ if(i==j) continue; memset(vis,0,sizeof(vis)); rep(k,1,min(i-1,j-1)) vis[sg[i-k][j-k]]=1; rep(k,1,i-1) if(i-k!=j) vis[sg[i-k][j]]=1; rep(k,1,j-1) if(i!=j-k) vis[sg[i][j-k]]=1; rep(k,0,10000) if(!vis[k]){ sg[i][j]=k; break; } } } int main() { int N,F=0,x,y,sum=0; getsg(); scanf("%d",&N); rep(i,1,N){ scanf("%d%d",&x,&y); sum^=sg[x][y]; if(x==y) F=1; } if(F||sum) puts("Y"); else puts("N"); return 0; }