codeforces 1651D Nearest Excluded Points

最近打算每天做一道codeforces 1800-2000难度的题活跃一下思维,然后记录一下自己没有解出来或是解法很巧妙的题。这道题来自1651D Nearest Excluded Points,题目大致是给出一个长度为n的数组,每一个元素保存着一个点的二维坐标,目标是找出距离每个点最近的点,且这个最近的点不在者n个点内。与这些点距离最近的点可能是距离为1、2、3...,首先获取这些最近点距离为1的点,然后最近点距离为2点必定是与最近点距离为1的点挨着的,因此最近点距离为2的点对应的最近点就是它们挨着的最近点距离为1的店对应的最近点,在代码中由ans[{nx, ny}] = ans[{x,y}]这一步体现出来,然后以此类推可计算出最近点距离为3的点,直到所有点计算完毕。

#include<bits/stdc++.h>

using namespace std;

int main()
{
    int n;
    scanf("%d", &n);
    vector<pair<int, int>> a(n);
    for(auto &[x, y]: a) scanf("%d %d", &x, &y);

    map<pair<int,int>, pair<int,int>> ans;
    set<pair<int,int>> st(a.begin(), a.end());

    queue<pair<int, int>> q;
    int tx[] = {0, 0, 1, -1}, ty[] = {1, -1, 0, 0};
    for(auto [x, y]: a)
    {
        for(int i = 0; i < 4; ++i)
        {
            int nx = x + tx[i], ny = y + ty[i];
            if(st.count({nx, ny})) continue;
            ans[{x,y}] = {nx, ny};
            q.push({x,y});
            break;
        }
    }
    while(!q.empty())
    {
        int x = q.front().first, y = q.front().second;
        q.pop();
        for(int i = 0; i < 4; ++i)
        {
            int nx = x + tx[i], ny = y + ty[i];
            if(ans.count({nx, ny}) || !st.count({nx, ny})) continue;
            ans[{nx, ny}] = ans[{x,y}];
            q.push({nx, ny});
        }

    }
    for(auto [x, y]: a)
    {
        auto it = ans[{x,y}];
        printf("%d %d\n", it.first, it.second);
    }

    return 0;
}

posted @ 2022-03-29 23:05  South1999  阅读(48)  评论(0编辑  收藏  举报