题目描述
给出数字 N(1<=N<=10000), (1<=x<=1000), Y(1<=Y<=1000) ,代表有N 个敌人分布一个 X 行 Y 列的矩阵上,矩形的行号从 0 到 X-1,列号从 0 到Y-1 再给出四个数字 x1,y1,x2,y2,代表你要从点(x1,y1)移到(x2,y2)。在移动的过程中你当然希望离敌人的距离的最小值最大化,现在请求出这个值最大可以为多少,以及在这个前提下,你最少要走多少步才可以回到目标点。注意这里距离的定义为两点的曼哈顿距离,即某两个点的坐标分为 (a,b),(c,d),那么它们的距离为|a-c|+|b-d|。
输入描述
第一行给出数字 N, X, Y 第二行给出 x1,y1,x2,y2 下面将有 N 行,给出 N 个敌人所在的坐标
输出描述
在一行内输出你离敌人的距离及在这个距离的限制下,你回到目标点最少要移动多少步。
样例输入
2 5 6
0 0 4 0
2 1 2 3
样例输出
2 14
数据范围及提示
30%: n=1
100%:1<=n<=1000 ,1<=x<=1000, 1<=y<=1000
题目来源:黄学长博客http://hzwer.com/4598.html
这题就是先用一个灌水法处理出每个点到最近的点的距离。然后二分到敌人的距离,输出步数。
这题别忘了对起点判断距离是否合法!!!被随机数据卡死在没判断这个。。。。
代码如下:
#include
#include
#include
#include
#include
using namespace std;
const int maxn=1005;
bool vis[maxn][maxn];
int dis[maxn][maxn];
struct dqs
{
int x,y,step;
}hh[maxn];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
queue q;
int n,x,y,sx,sy,ex,ey,ans=0,r;
int xex,yey;
bool check(int xx,int yy)
{
if(xx>=0&&xx=0&&yyreturn true;
return false;
}
void waterfill()
{
for(int i=1;i<=n;i++)
{
dqs now;
now.x=hh[i].x;
now.y=hh[i].y;
now.step=0;
q.push(now);
}
while(!q.empty())
{
dqs head=q.front();
q.pop();
for(int i=0;i<4;i++)
{
dqs now;
now.x=head.x+dx[i];
now.y=head.y+dy[i];
if(check(now.x,now.y))
{
vis[now.x][now.y]=1;
now.step=head.step+1;
dis[now.x][now.y]=now.step;
r=max(r,now.step);
q.push(now);
}
}
}
}
bool bfs(int mid)
{
dqs fir;
fir.x=sx;
fir.y=sy;
fir.step=0;
vis[fir.x][fir.y]=1;
if(dis[fir.x][fir.y]return false; //之前没有加该语句判断起点是否合法
q.push(fir);
while(!q.empty())
{
dqs head=q.front();
q.pop();
dqs now;
for(int i=0;i<4;i++)
{
now.x=head.x+dx[i];
now.y=head.y+dy[i];
if(now.x>=0&&now.x=0&&now.y=mid)
{
vis[now.x][now.y]=1;
now.step=head.step+1;
if(now.x==ex&&now.y==ey)
{
ans=now.step;
return true;
}
q.push(now);
}
}
}
return false;
}
bool erfen(int x)
{
while(!q.empty())
q.pop();
memset(vis,0,sizeof(vis));
if(bfs(x)) return true;
return false;
}
int main()
{
scanf("%d%d%d",&n,&x,&y);
int xx,yy;
scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&xx,&yy);
hh[i].x=xx;
hh[i].y=yy;
hh[i].step=0;
vis[hh[i].x][hh[i].y]=1;
dis[hh[i].x][hh[i].y]=0;
}
waterfill();
int l=0;
r+=1;
while(r-l>1)
{
int mid=(l+r)>>1;
if(erfen(mid)) l=mid;
else r=mid;
}
printf("%d %d",l,ans);
return 0;
}