题目描述:
给出数字N(1<=N<=10000),X(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个敌人所在的坐标
输出:
在一行内输出你离敌人的距离及在这个距离的限制下,你回到目标点最少要移动多少步。
Sample input
2 5 6
0 0 4 0
2 1
2 3
Sample output
2 14
题解:
灌水完二分+bfs验证
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int n, X, Y, ans;
int x1, x2, y1, y2;
int map[1050][1050];
int mmp[1050][1050];
bool used[1050][1050];
int xx[5] = {0, 0, 0, 1, -1};
int yy[5] = {0, 1, -1, 0, 0};
struct qer
{
int x, y;
}dr[23333];
queue <qer> q;
queue <qer> qq;
void full()
{
for (int i = 1; i <= n; i++)
{
int lsx = dr[i].x;
int lsy = dr[i].y;
qq.push((qer){lsx, lsy});
used[lsx][lsy] = 1;
}
while (!qq.empty())
{
qer a = qq.front();
qq.pop();
for (int i = 1; i <= 4; i++)
{
int lx = a.x + xx[i];
int ly = a.y + yy[i];
if (lx < 0 || lx >= X || ly < 0 || ly >= Y || used[lx][ly])
continue;
else
{
map[lx][ly] = map[a.x][a.y] + 1;
used[lx][ly] = 1;
qq.push((qer){lx, ly});
}
}
}
}
bool check(int x)
{
while (!q.empty())
q.pop();
memset(mmp, 0, sizeof(mmp));
memset(used, 0, sizeof(used));
q.push((qer){x1, y1});
while (!q.empty())
{
qer a = q.front();
q.pop();
if (map[a.x][a.y] < x)
continue;
for (int i = 1; i <= 4; i++)
{
int lx = a.x + xx[i];
int ly = a.y + yy[i];
// cout << lx << " " << ly << endl;
if (lx < 0 || lx >= X || ly < 0 || ly >= Y || map[lx][ly] < x || used[lx][ly])
continue;
mmp[lx][ly] = mmp[a.x][a.y] + 1;
if (lx == x2 && ly == y2)
{
ans = mmp[lx][ly];
return 1;
}
q.push((qer){lx, ly});
used[lx][ly] = 1;
}
}
return 0;
}
int main()
{
freopen("escape.in", "r", stdin);
freopen("escape.out", "w", stdout);
cin >> n >> X >> Y;
cin >> x1 >> y1 >> x2 >> y2;
for (int i = 1; i <= n; i++)
scanf("%d%d", &dr[i].x, &dr[i].y);
int l = 0, r = 10000;
full();
// for (int i = 0; i < X; i++)
// {
// for (int j = 0; j < Y; j++)
// {
// cout << map[i][j] << " ";
// }
// puts("");
// }
while (r - l > 1)
{
int mid = (r + l) / 2;
if (check(mid))
l = mid;
else
r = mid;
// cout << mid << endl;
}
if (check(l))
cout << l << " " << ans << endl;
else
cout << r << " " << ans << endl;
return 0;
}