还是跟之前的博弈题一样 暴力打SG表
之前每次循环都memset(book,0,sizeof(book)) 这里的数据比较大。所以用一个技巧,只要在开始memset一次。然后之后设book[...]=i+1 然后判断 if(book[k]!=i+1)是否成立就好了。
187ms 好险。
AC代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define maxn 10005
int T,s,n,book[maxn],a[maxn],f[105],sg[maxn],matc[maxn],m;
using namespace std;
int main()
{
sg[0]=0;//预处理 没得取的话为0 必输态
while(scanf("%d",&s)==1&&s)
{
for(int i=0;i<s;i++)scanf("%d",&f[i]);
f[s]=999999999;
s++;
sort(f,f+s);
cin>>T;
m=0;
memset(sg,0,sizeof(sg));
memset(book,0,sizeof(book));
for(int i=0;i<maxn;i++)
{
int tmax=0;
for(int j=0;f[j]<=i;j++)
{
book[sg[i-f[j]]]=i+1;
tmax=max(tmax,sg[i-f[j]]);
}
for(int k=0;k<=tmax+1;k++)
{
if(book[k]!=i+1)
{
sg[i]=k;
break;
}
}
}
while(T--)
{
cin>>n;
for(int i=0;i<n;i++)scanf("%d",&a[i]);
sort(a,a+n);
//for(int i=0;i<=a[n-1];i++)cout<<sg[i]<<" ";
//cout<<endl;
int res=0;
for(int i=0;i<n;i++)res^=sg[a[i]];
if(res)matc[m++]=1;
else matc[m++]=0;
}
for(int i=0;i<m;i++)
{
if(matc[i])printf("W");
else printf("L");
}
cout<<endl;
}
}