您的位置:首页 > 其它

SG函数(hdu 1847 && poj 2960 && 1849)

2014-04-14 11:50 337 查看
HDU 1847题目:点击打开链接

SG函数的一个很基础的题目

看其他人写的,除了用SG函数,还有更简便的方法,就是能被3整除的都是Cici赢。

#include <stdio.h>
#include <string.h>

int s[11] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024};
int sg[1010];

int getsg(int x)
{
int i;
if(sg[x] != -1)
return sg[x];
bool hash[110];
memset(hash, 0, sizeof(hash));
for(i = 0; i < 11; i++)
{
if(x >= s[i])
{
sg[x - s[i]] = getsg(x - s[i]);
hash[sg[x - s[i]]] = 1;
}
}
for(i = 0; i < 110; i++)
{
if(hash[i] == 0)
break;
}
return i;
}

int main (void)
{
int i;
memset(sg, -1, sizeof(sg));
sg[0] = 0;
for(i = 1; i < 1010; i++)
sg[i] = getsg(i);
int n;
while(scanf("%d", &n) != EOF)
{
if(sg
== 0)
printf("Cici\n");
else
printf("Kiki\n");
}
return 0;
}


POJ 2960题目:点击打开链接

题目就是一个变形了的nim,n堆石子,不再是选择一堆随便取,而是规定了取的数量。

也就是SG函数的应用,nim博弈中,因为选择了某一堆以后就可以取这一堆中的任意石子,也就是SG[ x ] = x,其实nim博弈中的把所以堆石子的数目异或起来来判断结果,也是用到了SG函数,因为石子数的SG值等于石子数本身(SG[ x ] = x),所以为了简单就直接把石子数都异或起来,而这一题因为SG[ x ] = x不成立了,所以要把每次SG求出来,再求SG值异或和来判断结果。

#include <stdio.h>
#include <string.h>

int s[110];
int sg[10010];
int n, m;

int getsg(int x)
{
if(sg[x] != -1)
return sg[x];
int i;
bool hash[110];
memset(hash, 0, sizeof(hash));
for(i = 0; i < n; i++)
{
if(x >= s[i])
{
sg[x - s[i]] = getsg(x - s[i]);
hash[sg[x - s[i]]] = 1;
}
}
for(i = 0; i < 110; i++)
{
if(hash[i] == 0)
break;
}
return i;
}

int main (void)
{
int i;
while(scanf("%d", &n) != EOF)
{
if(n == 0)
break;
char ans[110], k = 0;
int a, j, l;
for(i = 0; i < n; i++)
scanf("%d", &s[i]);

memset(sg, -1, sizeof(sg));
sg[0] = 0;
for(i = 1; i < 10010; i++)
sg[i] = getsg(i);
/*
for(i = 0; i < 8; i++)
{
printf("%d ", sg[i]);
}
printf("\n");
*/
scanf("%d", &m);
for(i = 0; i < m; i++)
{
int sum = 0;
scanf("%d", &l);
for(j = 0; j < l; j++)
{
scanf("%d", &a);
sum ^= sg[a];
}
if(sum == 0)
ans[k ++] = 'L';
else
ans[k ++] = 'W';
}
for(i = 0; i < k; i++)
printf("%c", ans[i]);
printf("\n");
}
return 0;
}


HDU1849

赤裸裸的nim博弈,当然,如上面那题所说,也可以用SG函数来做,因为nim博弈,SG[ x ] = x。

#include <stdio.h>
#include <string.h>

int sg[1010];

int getsg(int x)
{
int i;
if(sg[x] != -1)
return sg[x];
bool hash[1010];
memset(hash, 0, sizeof(hash));
for(i = 1; i < 1010; i++)
{//注意i从1开始
if(x >= i)
{
sg[x - i] = getsg(x - i);
hash[sg[x - i]] = 1;
}
if(x < i)
break;
}
for(i = 0; i < 1010; i++)
{
if(hash[i] == 0)
break;
}
return i;
}

int main (void)
{
int n, a, i;

memset(sg, -1, sizeof(sg));

sg[0] = 0;
for(i = 1; i < 1010; i++)
sg[i] = getsg(i);

while(scanf("%d", &n) != EOF)
{
if(n == 0)
break;
int sum = 0;
for(i = 0; i < n; i++)
{
scanf("%d", &a);
sum ^= sg[a];
}
if(sum == 0)
printf("Grass Win!\n");
else
printf("Rabbit Win!\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: