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 |
//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介绍得不错
/*
*/
//摘自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;
}