题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1536
利用sg模板可以做出来,代码如下,但很可能超时:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define H 10001
#define K 101
using namespace std;
int a[K];
int sg[H];
bool vis[H];
int k; //可选步数的个数
//sg函数模板
void getSg()
{
int i, j;
sg[0] = 0;
for(i=1; i<H; i++)
{
memset(vis, 0, sizeof(vis));
for(j=1; j<=k && a[j]<=i; j++ )
vis[sg[i-a[j]]]=1;
for(j=0; j<H; j++ )
{
if(!vis[j])
{
sg[i] = j;
break;
}
}
}
}
int main()
{
int i, j, m, l, h, tmp;
while(scanf("%d", &k) && k)
{
for(i=1; i<=k; ++i)
scanf("%d", &a[i]);
sort(a+1, a+k+1);
getSg();
scanf("%d", &m);
while(m--)
{
scanf("%d", &l);
tmp = 0;
while(l--)
{
scanf("%d", &h);
tmp = tmp ^ sg[h];
}
if(tmp == 0)
printf("L");
else
printf("W");
}
printf("\n");
}
return 0;
}
如果动用获得单个数的sg值得模版,采用类似于“记忆化搜索”的方式,用到哪个sg值,现求就好了,求过的就存好,下一次用到直接调用,这样能省去不少时间。代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define H 10001
#define K 101
using namespace std;
int a[K];
int sg[H];
bool vis[H];
int k;
int getSg(int m)
{
int vis[101] = {0};
int i;
for(i=0; i<k; ++i)
{
if(m-a[i] < 0)
break;
if(sg[m-a[i]] == -1)
sg[m-a[i]] = getSg(m-a[i]);
vis[sg[m-a[i]]] = 1;
}
for(i=0; ; i++)
if(!vis[i])
return i;
}
int main()
{
int i, j, m, l, h, tmp;
while(scanf("%d", &k) && k)
{
memset(a, 0, sizeof(a));
for(i=0; i<k; ++i)
scanf("%d", &a[i]);
sort(a, a+k);
scanf("%d", &m);
memset(sg, -1, sizeof(sg));
while(m--)
{
scanf("%d", &l);
tmp = 0;
while(l--)
{
scanf("%d", &h);
if(sg[h] == -1)
sg[h] = getSg(h);
tmp = tmp ^ sg[h];
}
if(tmp == 0)
printf("L");
else
printf("W");
}
printf("\n");
}
return 0;
}