CQOI2013 棋盘游戏
题目链接:戳我
emmmm因为B的活动范围比A广,所以只要不是第一步被A吃掉,终究会赢得胜利的(根本不会有平局嘛)
上面那个结论一定要先确定好,不知道结果的话没法对抗搜索的。
然后就.....我们的目的是让B尽快地赢,A尽可能地多跑一会儿,所以前者取min后者取max。
QAQ 但是讲道理应该步数不应该是2*n以内嘛.....我也不太明白,等dalao们CTS/APIO回来之后问问他们我再update吧......
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define MAXN 25
using namespace std;
int n,m,black,white,r1,r2,c1,c2;
int sum[MAXN][MAXN][MAXN][MAXN][2][60];
int move_x[4]={-1,1,0,0},move_y[4]={0,0,-1,1};
int move_x2[8]={-1,-2,1,2,0,0,0,0},move_y2[8]={0,0,0,0,-1,-2,1,2};
inline int search(int r1,int c1,int r2,int c2,int op,int cnt)
{
if(cnt>3*n) return 0x3f3f3f3f;
if(sum[r1][c1][r2][c2][op][cnt]) return sum[r1][c1][r2][c2][op][cnt];
// printf("[%d %d] [%d %d] %d\n",r1,c1,r2,c2,op);
if(r1==r2&&c1==c2)
{
if(op==0) sum[r1][c1][r2][c2][op][cnt]=0;
else sum[r1][c1][r2][c2][op][cnt]=0x3f3f3f3f;
// printf("bingo! %d\n",sum[r1][c1][r2][c2][op][cnt]);
return sum[r1][c1][r2][c2][op][cnt];
}
int cur_ans;
if(op==0)
{
cur_ans=0;
for(int i=0;i<=3;i++)
{
int xx=r1+move_x[i];
int yy=c1+move_y[i];
if(xx<1||xx>n||yy<1||yy>n) continue;
int cur=search(xx,yy,r2,c2,1,cnt+1);
cur_ans=max(cur_ans,cur);
}
}
else
{
cur_ans=0x3f3f3f3f;
for(int i=0;i<=7;i++)
{
int xx=r2+move_x2[i];
int yy=c2+move_y2[i];
if(xx<1||xx>n||yy<1||yy>n) continue;
int cur=search(r1,c1,xx,yy,0,cnt+1);
cur_ans=min(cur_ans,cur);
}
}
// printf("%d\n",sum[r1][c1][r2][c2][op][cnt]);
sum[r1][c1][r2][c2][op][cnt]=++cur_ans;
return cur_ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
// freopen("ce.out","w",stdout);
#endif
scanf("%d%d%d%d%d",&n,&r1,&c1,&r2,&c2);
if(abs(r1-r2)+abs(c1-c2)<=1) printf("WHITE 1\n");
else
{
printf("BLACK ");
int ans=search(r1,c1,r2,c2,0,0);
printf("%d\n",ans);
}
return 0;
}