题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1851
题意:有n堆石子,每一堆有mi个,且每次可以取[1,Li],问先手必胜还是后手必胜。
思路:数据很小,直接将所有状态的sg值计算出来,然后对于每一堆直接把sg值取出来异或判断结果。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
#include <stack>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=22;
int sg[maxn][maxn],vis[maxn];
void init()
{
int i,j,k;
for(k=1;k<=20;k++)
{
sg[k][0]=0;
for(i=1;i<=20;i++)
{
memset(vis,0,sizeof(vis));
for(j=1;j<=min(i,k);j++)
vis[sg[k][i-j]]=1;
for(j=0;;j++)if(!vis[j]){sg[k][i]=j;break;}
}
}
}
int main()
{
int n,T;
init();
cin>>T;
while(T--)
{
cin>>n;
int ans=0,a,b,i;
for(i=0;i<n;i++)
{
cin>>a>>b;
ans^=sg[b][a];
}
if(ans==0)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}