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;
}