博弈题

牛牛牛

hdu1848

题意:三堆石子,每次能从一堆中取斐波那契数个,最后去不了的输,问谁赢
解:sg打表版子题,每个单独看,最后异或起来求解,对于一个,打个表

#include
#include
int f[3000],sg[3000];
void init(){
	f[1]=1;
	f[2]=2;
	for(int i=3;i<1000;i++){
		f[i]=f[i-1]+f[i-2];
		if(f[i]>1000)	break;
	}
}
void get_sg(){
	for(int i=1;i<1000;i++){
		int vis[3000];
		memset(vis,0,sizeof(vis));
		for(int j=1;f[j]<=i;j++)
			vis[sg[i-f[j]]]=1;
		for(int j=0;j<=1000;j++){
			if(!vis[j]){
				sg[i]=j;
				break;
			}
		}
	}
}
int main(){
	init();
	get_sg();
	int n,m,p;
	while(scanf("%d%d%d",&n,&m,&p)!=EOF&&(n||m||p)){
		if(sg[n]^sg[m]^sg[p])	printf("Fibo\n");
		else printf("Nacci\n");
	}
	return 0;
} 

lightoj 1315

题意:给定一个棋盘,左上角为(0,0),棋盘中有多个骑士,每一个骑士只能按照图中的6种方式移动,两个人轮流移动棋盘中任意一个骑士,当轮到某一个人移动骑士时,棋盘中的骑士都已经不能移动了则判定为输,Alice先移动棋盘中的骑士,最后输出Alice和Bob谁赢谁输。
博弈题_第1张图片
sg函数的dfs写法

#include
#include
int sg[1000][1000];
int X[6]={1,-1,-1,-2,-3,-2};
int Y[6]={-2,-3,-2,-1,-1,1};
int get_sg(int x,int y){
	bool vis[1100]={0};
	if(sg[x][y]!=-1)	return sg[x][y];
	else{
		for(int i=0;i<6;i++){
			int newx=x+X[i];
			int newy=y+Y[i];
			if(newx>=0&&newy>=0)vis[get_sg(newx,newy)]=1;
		}
		for(int i=0;;i++)
			if(!vis[i]){
				sg[x][y]=i;
				break;
			}	
	}
	return sg[x][y];
}
int main(){
	memset(sg,-1,sizeof(sg));
	int t,ttt=0;
	scanf("%d",&t);
	while(t--){
		int n;
		scanf("%d",&n);
		int ans=0;
		for(int i=0;i<n;i++){
			int x,y;
			scanf("%d%d",&x,&y);
			
			ans^=get_sg(x,y);
		}
		if(ans==0)	printf("Case %d: Bob\n",++ttt);
		else printf("Case %d: Alice\n",++ttt);
	}
	return 0;
} 

你可能感兴趣的:(博弈)