bzoj 3106 //3106: [cqoi2013]棋盘游戏

bzoj 3106   //3106: [cqoi2013]棋盘游戏   //在线测评地址https://www.lydsy.com/JudgeOnline/problem.php?id=3106

//在线测评地址https://www.luogu.org/problem/P4576

更多题解,详见https://blog.csdn.net/mrcrack/article/details/90228694BZOJ刷题记录

Accepted 125412 kb 7852 ms C++/Edit 1712 B

bzoj 3106 //3106: [cqoi2013]棋盘游戏_第1张图片

//3106: [cqoi2013]棋盘游戏
//在线测评地址https://www.lydsy.com/JudgeOnline/problem.php?id=3106
//此文https://www.cnblogs.com/TheRoadToTheGold/p/8227335.html思路不错,摘抄如下:
/*
白棋如果第一步不能赢,那么一定输
因为可以黑棋走的距离比白棋大,黑棋可以下一步吃掉白棋,也可以下一步离开白棋的吃子范围
n才20,我们可以dfs搜索所有的局面求黑棋取胜的回合数
记录当前状态到游戏结束的回合数
如果现在白棋走,那它要尽可能的拖延时间,所以就是所有的后继状态取大
如果现在黑棋走,那它要尽快的取胜,所以就是所有的后继状态取小
边界是当两个棋子到同一位置时,根据前面的分析,应该必须是黑棋完成的最后一步
而dfs到下一回合,双方互换
所以当前如果是白棋,就return 0
如果是黑旗,就return 无穷大
*/
//关于Ans≤4∗N,此文https://blog.csdn.net/PhilipsWeng/article/details/47841649介绍得不错
/*

bzoj 3106 //3106: [cqoi2013]棋盘游戏_第2张图片

bzoj 3106 //3106: [cqoi2013]棋盘游戏_第3张图片

bzoj 3106 //3106: [cqoi2013]棋盘游戏_第4张图片

bzoj 3106 //3106: [cqoi2013]棋盘游戏_第5张图片

bzoj 3106 //3106: [cqoi2013]棋盘游戏_第6张图片

bzoj 3106 //3106: [cqoi2013]棋盘游戏_第7张图片

*/
//摘自https://www.cnblogs.com/ctlchild/p/4995806.html
//对抗搜索,f[x][y][a][b][c][d]表示当前谁走,走了几步,及位置。
//此文https://blog.csdn.net/onepointo/article/details/78243928代码写得不错。
//样例通过,提交Wrong_Answer    125412 kb    148 ms    C++/Edit    1153 B   2019-11-7
//经过一系列修改,样例通过,提交AC。2019-11-7 20:36
//dp[2][82][21][21][21][21]   2*82*21*21*21*21/1024/1024=30.42MB,内存占用比较多的原因,还是深搜引起的.2019-11-7 20:39
#include
#include
int dp[2][82][21][21][21][21],N,r1,c1,r2,c2;
int next1[][2]={{1,0},{-1,0},{0,1},{0,-1}};
int next2[][2]={{1,0},{-1,0},{0,1},{0,-1},{2,0},{-2,0},{0,2},{0,-2}};
int max(int a,int b){
    return a>b?a:b;
}
int min(int a,int b){
    return a }
int dfs(int who,int step,int x1,int y1,int x2,int y2){
    int i,j,nx,ny,ans;//此处错写成int i,j,nx,ny,ans=0;
    if(step>4*N)return 4*N;
    if(x1==x2&&y1==y2)//此处错写成if((r1==x2&&c1==y2)||(r2==x1&&c2==y1))
        return who?4*N:0;
    if(dp[who][step][x1][y1][x2][y2])return dp[who][step][x1][y1][x2][y2];
    if(!who){
        ans=0;//漏了此句
        for(i=0;i<4;i++){
            nx=x1+next1[i][0],ny=y1+next1[i][1];
            if(1<=nx&&nx<=N&&1<=ny&&ny<=N)ans=max(ans,dfs(1,step+1,nx,ny,x2,y2));//此处错写成if(1<=nx&&nx<=N&&1<=ny&&ny<=N)ans=max(ans,dp[1][step+1][nx][ny][x1][y1]);
        }
     }
    else{
        ans=4*N;//漏了此句
        for(i=0;i<8;i++){
            nx=x2+next2[i][0],ny=y2+next2[i][1];
            if(1<=nx&&nx<=N&&1<=ny&&ny<=N)ans=min(ans,dfs(0,step+1,x1,y1,nx,ny));//此处错写成if(1<=nx&&nx<=N&&1<=ny&&ny<=N)ans=max(ans,dp[1][step+1][nx][ny][x1][y1]);
        }
    }
    return dp[who][step][x1][y1][x2][y2]=ans+1;
}
int myabs(int a){
    return a>=0?a:-a;
}
int main(){
    memset(dp,0,sizeof(dp));
    scanf("%d%d%d%d%d",&N,&r1,&c1,&r2,&c2);
    if(myabs(r1-r2)+myabs(c1-c2)<=1) printf("WHITE 1\n");//此处错写成if(r1-r2+c1-c2<=1) printf("WHITE 1\n");
    else printf("BLACK %d\n",dfs(0,0,r1,c1,r2,c2));
    return 0;
}

 

你可能感兴趣的:(跟着大佬学算法)