3094Escape from Enemy Territory——zoj

思路
 
因为题中说了曼哈顿距离   所以在遍历中  每走一步就是一个距离   就缩小了难度(业界良心。。)
又说要找最小最大距离。。
对于每一个点的预处理最小距离就是一定了


然后再找到那个最小最大距离
然后再来找步数

两个一定要分开找  不然时间上要t


因为找标准要logn次   就要清理logn次哈希表  如果把标准与步数一起更新  就要清理2*logn次哈希表
如果分开找  就只用清理logn+1次哈希表   就不会超时了。。。。 


预处理

dis[i][j]表示i,j到最近的一个敌营的距离
如果暴力来  时间上o(n^3)1000*1000*1000t定了
就要机智一点,,
用bfs来实现   将所有敌营加到队列里   如果当前点的距离算过了
就continue   因为bfs先到的一定是最短距离
这样就只有o(n^2)
ok了。

找最小最大距离
这个肯定二分找了。。。不然呢、
在预处理的时候   记录下所有距离中的最大值  
最小值就不管了  一定是0 (没想到军爷(不用在意这些细节)们居然可以直接穿过敌营  七进七出还战术撤退啊。。。O(∩_∩)O~)
具体步骤见后代码


找到最小步数
裸bfs无压力
找到了二分出来的标准
就用标准来进行真实意义上的bfs
找到最短路
判断如果当前的距离在标准允许内就push  不然就continue





#include/*预处理出i,j点到敌营 的最小值  先二分bfs找到一个离敌营最大值   在用标准bfs出最小步数*/
#include
#include
#include
using namespace std;
const int dx[5]={0,-1,1,0,0};
const int dy[5]={0,0,0,-1,1};
int hash[1000+10][1000+10];//最小step
int ste[1000+10][1000+10];//最少step 
int maxn;
int l,r,mid;
struct edge
{
	int v,u;
	int step;
	int mins;
}cs,ns,ans,res;
queueq;
int dis[1000+10][1000+10];
int t;
int n,x,y;
int stx,sty,enx,eny;
void readdata()
{
	maxn=-1;
	while(!q.empty())
	q.pop();
	cs.step=0;
	cs.mins=0;
	cs.u=0;
	cs.v=0;
	ans=cs;
	memset(dis,0,sizeof(dis));
	memset(ste,0,sizeof(ste));
	scanf("%d%d%d",&n,&x,&y);
	scanf("%d%d%d%d",&stx,&sty,&enx,&eny);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&cs.u,&cs.v);
		dis[cs.u][cs.v]=-1;
		q.push(cs);
	}
}
void ready()
{
	while(!q.empty())
	{
		cs=q.front();
		q.pop();
		for(int i=1;i<=4;i++)
		{
			ns=cs;
			ns.u+=dx[i];
			ns.v+=dy[i];
			ns.step++;
			if(ns.u<=x-1&&ns.u>=0)
			if(ns.v<=y-1&&ns.v>=0)
			if(!dis[ns.u][ns.v])
			{
				dis[ns.u][ns.v]=ns.step;
				maxn=max(maxn,dis[ns.u][ns.v]);
				q.push(ns);
			}
		}
	}
	while(!q.empty())
	q.pop();
}
bool bfs_for_bz(int bz)
{
	memset(hash,0,sizeof(hash)) ;
	cs.u=stx;
	cs.v=sty;
	cs.mins=dis[stx][sty];
	q.push(cs);
	while(!q.empty())
	{
		cs=q.front();
		q.pop();
		for(int i=1;i<=4;i++)
		{
			ns=cs;
			ns.u+=dx[i];
			ns.v+=dy[i];			
			if(!(ns.u<=x-1&&ns.u>=0))
			continue;
			if(!(ns.v<=y-1&&ns.v>=0))
			continue;
			ns.mins=min(ns.mins,dis[ns.u][ns.v]);
			if(dis[ns.u][ns.v]==-1)
			ns.mins=0;
			if(ns.mins=0))
			continue;
			if(!(ns.v<=y-1&&ns.v>=0))
			continue;
			if(dis[ns.u][ns.v]==-1)
			dis[ns.u][ns.v]=0;
			if(dis[ns.u][ns.v]


你可能感兴趣的:(二分,搜索)