您的位置:首页 > 其它

hdu 1536 | hdu 1944 - S-Nim(博弈-SG)

2013-10-28 22:00 423 查看
题目很啰嗦,说白了就是sg函数的简单运用,因为还没有理解sg函数的原理,只能先套用模板了~~

代码入下:(递归式)

const int M = 10005;
int n, sg[M], f[105];
int getSG(int x)
{
int &ans = sg[x];
if(ans!=-1) return ans;
bool vis[110];
memset(vis,0,sizeof(vis));
for(int j = 0; f[j] <= x && j < n; ++j)
vis[getSG(x-f[j])] = 1;
for(int j = 0; ; ++j) {
if(vis[j]==0) {
ans = j;
break;
}
}
return ans;
}
int main()
{
int m, k, x;
while(scanf("%d", &n) && n) {
for(int i = 0; i < n; ++i) scanf("%d", &f[i]);
sort(f,f+n);
memset(sg,-1,sizeof(sg));
scanf("%d", &m);
while(m--) {
int ans = 0;
scanf("%d", &k);
while(k--) {
scanf("%d", &x);
ans ^= getSG(x);
}
if(ans) printf("W");
else printf("L");
}
printf("\n");
}
}

代码如下:(非递归式)

const int M = 10005;
int n, sg[M], f[105];
void getSG()
{
sg[0] = 0;
for(int i = 1; i < M; ++i) {
bool vis[105];
memset(vis, 0, sizeof(vis));
for(int j = 0; f[j] <= i && j < n; ++j)
vis[sg[i-f[j]]] = 1;
for(int j = 0; ; ++j)
if(!vis[j]) {
sg[i] = j;
break;
}
}
}
int main()
{
int m, k, x;
while(scanf("%d", &n) && n) {
for(int i = 0; i < n; ++i) scanf("%d", &f[i]);
sort(f,f+n);
getSG();
scanf("%d", &m);
while(m--) {
int ans = 0;
scanf("%d", &k);
while(k--) {
scanf("%d", &x);
ans ^= sg[x];
}
if(ans) printf("W");
else printf("L");
}
printf("\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: