博弈简单题目

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


HDU 1536


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值