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 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; }
原文:http://blog.csdn.net/w20810/article/details/48035561