• [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

    #@^!?*%$!!!

    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define maxn 109
    #define rep(i,l,r) for (int i=l;i<=r;i++)
    #define down(i,l,r) for (int i=l;i>=r;i--)
    #define clr(x,y) memset(x,y,sizeof(x))
    #define ll long long
    #define inf int(1e9)
    using namespace std;
    int dx[8]={1,0,-1,0,2,0,-2,0};
    int dy[8]={0,1,0,-1,0,2,0,-2};
    int f[2][69][21][21][21][21];
    int n,a,b,c,d; 
    int read(){
        int x=0,f=1; char ch=getchar();
        while (!isdigit(ch)) {
            if (ch=='-') f=-1; ch=getchar();
        }
        while (isdigit(ch)){
            x=x*10+ch-'0'; ch=getchar();
        }
        return x*f;
    }
    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=0,xx=0,yy=0;
        if (x){
            ans=inf;
            rep(j,0,7) {
                xx=c+dx[j]; yy=d+dy[j];
                if (1<=xx&&xx<=n&&1<=yy&&yy<=n) ans=min(ans,dfs(0,y+1,a,b,xx,yy));
            }
        }   
        else {
            rep(j,0,3){
                xx=a+dx[j]; yy=b+dy[j];
                if (1<=xx&&xx<=n&&1<=yy&&yy<=n) ans=max(ans,dfs(1,y+1,xx,yy,c,d));
            }
        }
        ans++;
        f[x][y][a][b][c][d]=ans;
        return f[x][y][a][b][c][d]; 
    }
    int main(){
        n=read(); a=read(); b=read(); c=read(); d=read();
        if (abs(a-c)+abs(b-d)==1) puts("WHITE 1");
        else printf("BLACK %d",dfs(0,0,a,b,c,d));
        return 0;
    }
  • 相关阅读:
    hdu 1251(字典树)(3种方法)
    HDU 2203(KMP算法)
    九度oj 题目1335:闯迷宫
    poj3894 bfs+记录路径
    状压dp--P2704
    状压dp--洛谷P2622
    动态规划--牛客多校number
    完全背包
    01背包--hdu
    莫比乌斯反演模板--Gym 101982B
  • 原文地址:https://www.cnblogs.com/keshuqi/p/6338066.html
Copyright © 2020-2023  润新知