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
",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
",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
",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
");
	else 
	{
		printf("BLACK ");
		int ans=search(r1,c1,r2,c2,0,0);
		printf("%d
",ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/fengxunling/p/10860264.html