NOIP模拟赛 大逃亡

题目描述:

给出数字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;
}

 

上一篇
下一篇