【对抗搜索】 bzoj3106 [cqoi2013]棋盘游戏

1 篇文章 0 订阅
1 篇文章 0 订阅

Description

一个n*n(n>=2)棋盘上有黑白棋子各一枚。游戏者A和B轮流移动棋子,A先走。

l         A的移动规则:只能移动白棋子。可以往上下左右四个方向之一移动一格。

l         B的移动规则:只能移动黑棋子。可以往上下左右四个方向之一移动一格或者两格。

和通常的“吃子”规则一样,当某游戏者把自己的棋子移动到对方棋子所在的格子时,他就赢了。两个游戏者都很聪明,当可以获胜时会尽快获胜,只能输掉的时候会尽量拖延时间。你的任务是判断谁会赢,需要多少回合。

比如n=2,白棋子在(1,1),黑棋子在(2,2),那么虽然A有两种走法,第二个回合B总能取胜。

Input

输入仅一行,包含五个整数n, r1, c1, r2, c2,即棋盘大小和棋子位置。白色棋子在(r1,c1),黑色棋子在(r2,c2)(1<=r1,c1,r2,c2<=n)。黑白棋子的位置保证不相同。

Output

输出仅一行,即游戏结果。如果A获胜,输出WHITE x;如果B获胜,输出BLACK x;如果二者都没有必胜策略,输出DRAW。

Sample Input

2 1 1 2 2

Sample Output

BLACK 2

HINT

n<=20

 

数据范围较小

对于本题,显然白棋腿短,如果第一步吃不掉黑棋就再也吃不到了,所以白棋的策略就是尽量拖延时间。 
再来看黑棋,显然黑棋如果第一步不被吃掉是必胜的,因为黑棋会不断地缩小白棋的活动范围(换个方法想,黑棋腿长,一定不会输,又不会出现和棋局面,所以黑必胜),所以黑棋的策略是尽快吃掉白棋。 

可以证明B一定能在n * 4步以内获胜

可以考虑暴力对抗搜索

对抗搜索 用于解决博弈问题 

f[x][y][a][b][c][d]表示当前谁走,走了几步,及位置。

状态中记录操作者是谁  由操作者目的不同 状态转移方程也不同

注意代码细节

#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int inf=1e9;
int n,a,b,c,d,f[2][69][21][21][21][21];
int dx[8]={1,0,-1,0,2,0,-2,0};
int dy[8]={0,1,0,-1,0,2,0,-2};
int dfs(int x,int y,int a,int b,int c,int d)
 {if(y>3*n) return inf;
  if(a==c && b==d){if(x) return inf; return 0;}
  if(f[x][y][a][b][c][d]) return f[x][y][a][b][c][d];
  int ans,xx,yy;
  if(x)
    {ans=inf;
     for(int i=0;i<=7;i++)
      {xx=c+dx[i],yy=d+dy[i];
       if(1<=xx && xx<=n && 1<=yy && yy<=n)
            ans=min(ans,dfs(0,y+1,a,b,xx,yy));
      }
    }
  else 
     {ans=0;
      for(int i=0;i<=3;i++)
       {xx=a+dx[i],yy=b+dy[i];
       if(1<=xx && xx<=n && 1<=yy && yy<=n)
            ans=max(ans,dfs(1,y+1,xx,yy,c,d));
       }
     }
  ans++;
  return f[x][y][a][b][c][d]=ans;	   
 }
int main()
{scanf("%d%d%d%d%d",&n,&a,&b,&c,&d);	
 	
 if(abs(a-c)+abs(b-d)<=1)	printf("WHITE 1");
 else                       printf("BLACK %d",dfs(0,0,a,b,c,d));	
	
return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值