博弈题
hdu1848
题意:三堆石子,每次能从一堆中取斐波那契数个,最后去不了的输,问谁赢
解:sg打表版子题,每个单独看,最后异或起来求解,对于一个,打个表
#include<cstdio>
#include<cstring>
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谁赢谁输。
sg函数的dfs写法
#include<cstdio>
#include<cstring>
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;
}