版权声明:转载注明下出处就行了。 https://blog.csdn.net/LJD201724114126/article/details/84553080
题目链接:哆啦A梦传送门
题意:nim游戏变形,只不过每次取得个数只能在集合S{s1,s2,...,sk}选一个来取,
输入k,表示紧接着S集合有k个元素
输入m,表示m次询问,每次给一个数l,表示有l堆,每堆的数量。
先手win,输出 “W”,否则,输出“L”。
题解:直接写个SG函数就行了。
注意一点的是,集合元素值要排序一下,不然会出错。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=10010;
int f[110],book[110];
int SG[maxn];
int k;
void getSG()
{
memset(SG,0,sizeof(SG));
SG[0]=0;
for(int i=1;i<maxn;i++)
{
memset(book,0,sizeof(book));
for(int j=0;f[j]<=i&&j<k;j++){
book[SG[i-f[j]]]=1;
}
for(int j=0;;j++){
if(!book[j]){
SG[i]=j;break;
}
}
}
}
int main()
{
while(scanf("%d",&k)&&k)
{
for(int i=0;i<k;i++)
scanf("%d",&f[i]);
sort(f,f+k); ///排序一下,不排会wa
getSG();
int m,num,item;
int sum=0;
scanf("%d",&m);
while(m--)
{
scanf("%d",&num);
sum=0;
while(num--)
{
scanf("%d",&item);
sum^=SG[item];
}
if(sum) printf("W");
else printf("L");
}
puts("");
}
return 0;
}