HDU 1846 有n个石头,2个人,每次只能拿m个,谁最后拿完谁赢。
假如n%(m+1)==0,第一个人拿x个,那么第二个人拿m+1-x个,第一个人拿完之后,第二个人始终能拿。
HDU 2147 有n*m个格子和一个棋子,棋子初始在(1,m),每次移动棋子只能到3个位置(左边,下边和左下),谁不能走谁就输。
HDU 2188 和HDU1846一样
HDU 2149 和HDU1846类似
HDU 1847 有n张牌,可以拿2的幂次(即:1,2,4,8,16…)张拍,谁先拿完谁赢。
打SG函数表,貌似打的是错的,为什么A了.......对sg函数不熟,求解答
#include <iostream>
#include <cstdio>
using namespace std;
int sg[1007],f[1007];
void work()
{
int i,j;
for(i=1;i<=1000;i*=2)
sg[i]=i;
for(i=2;i<=1000;i++) if(!sg[i])
{
fill(f,f+i,0);
for(j=1;j<i;j*=2)
f[sg[i-j]]=1;
for(j=0;j<i;j++)
if(!f[j])
{
sg[i]=j;
break;
}
}
}
int main()
{
work();
int x;
while(scanf("%d",&x)!=EOF)
printf("%s\n",sg[x]?"Kiki":"Cici");
return 0;
}
HDU 1849 最最简单的Nim博弈。
HDU 1850 基本的Nim博弈,算第一步能使自己必胜的方案数的时候,直接枚举每堆扑克a[i],判断a[i]将要变成的值sum^a[i]是否比a[i]就行了。
HDU1848 3堆石头,每次拿走其中一堆里面的fib[x]个,问谁先拿完。
像HDU1847那样打表就WA了。换了个姿势打表,对SG函数不熟啊,,,,,
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1007;
int sg[maxn],f[maxn],fib[30];
void work()
{
int i,j,nfib;
fib[1]=1;
fib[2]=2;
for(nfib=3;fib[nfib-1]+fib[nfib-2]<=2000;nfib++)
fib[nfib]=fib[nfib-1]+fib[nfib-2];
for(i=1;i<=1000;i++)
{
fill(f,f+i+1,0);
for(j=1;fib[j]<=i;j++)
f[sg[i-fib[j]]]=1;
for(j=0;j<maxn;j++)
if(!f[j])
{
sg[i]=j;
break;
}
}
}
int main()
{
work();
int a,b,c;
while(scanf("%d%d%d",&a,&b,&c),(a||b||c))
printf("%s\n",(sg[a]^sg[b]^sg[c])?"Fibo":"Nacci");
return 0;
}
HDU 1517