zoukankan      html  css  js  c++  java
  • bzoj3106 [cqoi2013]棋盘游戏

    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

    正解:对抗搜索。

    首先如果先手不能在第一步就赢,那么他就必输,因为后手可以把先手围在角落里。

    然后设$f[0/1][y][a][b][c][d]$表示当前是先手/后手,总共走了几步,先手在$(a,b)$,后手在$(c,d)$,直接按照对抗搜索的方法转移就行。

    以前没有写过对抗搜索,还是挂一个链接:博弈基础——极大极小搜索

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define inf (1<<30)
     6 
     7 using namespace std;
     8 
     9 const int d1[8]={1,0,-1,0,2,0,-2,0};
    10 const int d2[8]={0,1,0,-1,0,2,0,-2};
    11 
    12 int f[2][65][21][21][21][21],n,a,b,c,d;
    13 
    14 il int gi(){
    15   RG int x=0,q=1; RG char ch=getchar();
    16   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    17   if (ch=='-') q=-1,ch=getchar();
    18   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    19   return q*x;
    20 }
    21 
    22 il int dfs(RG int x,RG int y,RG int a,RG int b,RG int c,RG int d){
    23   if (y>3*n) return inf; if (a==c && b==d) return x?inf:0;
    24   if (f[x][y][a][b][c][d]) return f[x][y][a][b][c][d]; RG int res;
    25   if (x){
    26     res=inf;
    27     for (RG int i=0,X,Y;i<8;++i){
    28       X=c+d1[i],Y=d+d2[i];
    29       if (X>=1 && X<=n && Y>=1 && Y<=n)
    30     res=min(res,dfs(x^1,y+1,a,b,X,Y));
    31     }
    32   } else{
    33     res=0;
    34     for (RG int i=0,X,Y;i<4;++i){
    35       X=a+d1[i],Y=b+d2[i];
    36       if (X>=1 && X<=n && Y>=1 && Y<=n)
    37     res=max(res,dfs(x^1,y+1,X,Y,c,d));
    38     }
    39   }
    40   return f[x][y][a][b][c][d]=res+1;
    41 }
    42 
    43 int main(){
    44 #ifndef ONLINE_JUDGE
    45   freopen("chess.in","r",stdin);
    46   freopen("chess.out","w",stdout);
    47 #endif
    48   n=gi(),a=gi(),b=gi(),c=gi(),d=gi();
    49   if (abs(a-c)+abs(b-d)==1) puts("WHITE 1");
    50   else printf("BLACK %d
    ",dfs(0,0,a,b,c,d));
    51   return 0;
    52 }
  • 相关阅读:
    Hadoop 的版本问题
    SSH 端口转发原理
    KM算法
    最大流算法小结
    pku 2195 KM算法求最小权二分匹配
    SAP(最短增广路算法) 最大流模板
    最大流模板
    pku 1459 最大流 SAP
    pku Drainage Ditches 简单最大流 直接套模板 注意可能有重边
    推荐:吴军 谷歌黑板报 《浪潮之颠》
  • 原文地址:https://www.cnblogs.com/wfj2048/p/8016869.html
Copyright © 2011-2022 走看看