题目大意:
地图上有很多敌人据点,主角想要离这些据点越远越好,但是又要到达终点。
思路:
既然是越远越好又要到达终点,当然我们需要枚举他到底能离据点多远。
这个时候想着用二分枚举这个距离。
然后我们用一个bfs预处理出地图中所有的店离据点的最近距离。(第一次写bfs的预处理。。。)
接下来就是二分的过程了。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
int sx,sy,tx,ty;
int dx[] = {0,0,-1,1};
int dy[] = {-1,1,0,0};
bool vis[1005][1005];
int map[1005][1005];
int tot,n,m;
int maxdis,tans,ans;
struct Inf
{
int x,y,dep;
};
bool ok(int xx,int yy)
{
if(xx>=0&&xx<n&&yy>=0&&yy<m)return true;
return false;
}
void debug()
{
cout<<"---"<<endl;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
printf("%d ",map[i][j]);
}
puts("");
}
cout<<"---"<<endl;
}
void presolve()
{
queue<Inf>Q;
for(int i=1;i<=tot;i++)
{
Inf tmp;
scanf("%d%d",&tmp.x,&tmp.y);
tmp.dep=0;
map[tmp.x][tmp.y]=0;
Q.push(tmp);
}
Inf w,e;
while(!Q.empty())
{
w=Q.front();
Q.pop();
for(int k=0;k<4;k++)
{
e=w;
e.x+=dx[k];
e.y+=dy[k];
e.dep++;
if(ok(e.x,e.y)&&map[e.x][e.y]==-1)
{
map[e.x][e.y]=e.dep;
maxdis=max(maxdis,e.dep);
Q.push(e);
}
}
}
}
bool bfs(int dis)
{
queue<Inf>Q;
Inf w,e;
w.x=sx;
w.y=sy;
w.dep=0;
Q.push(w);
while(!Q.empty())
{
w=Q.front();
Q.pop();
for(int k=0;k<4;k++)
{
e=w;
e.x+=dx[k];
e.y+=dy[k];
e.dep++;
if(ok(e.x,e.y)&&!vis[e.x][e.y]&&map[e.x][e.y]>=dis)
{
if(e.x==tx && e.y==ty)
{
// cout<<dis<<"---"<<endl;
tans=e.dep;
return true;
}
vis[e.x][e.y]=true;
Q.push(e);
}
}
}
return false;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(map,-1,sizeof(map));
maxdis=-1;ans=-1;
scanf("%d%d%d",&tot,&n,&m);
scanf("%d%d%d%d",&sx,&sy,&tx,&ty);
presolve();
// debug();
int bot=0,top=maxdis+10,mid;
while(bot<top)
{
mid=(bot+top)>>1;
if(map[sx][sy]<mid)
{
top=mid;
continue;
}
memset(vis,false,sizeof vis);
if(bfs(mid))
{
bot=mid+1;
ans=max(ans,tans);
// printf("tans=%d \n",tans);
}
else top=mid;
}
printf("%d %d\n",bot-1,ans);
}
return 0;
}