D Nearest Excluded Points
暴力写T
共分为两种情况的点:上下左右有空余的点,上下左右都被其余点占用的点
先观察符合条件的点,即上下左右有空白的点,曼哈顿距离可以直接计算出来,再将符合条件的点加入队列。但是内部被点层层包裹的点就不能再暴力一圈一圈判断了,通过加入队列的点去判断,通过对队列的点a通过上下左右四个方向的进行bfs搜索,被搜到点b的答案就是a答案,因为b能保证理a是最近的,而a的答案一定最小,所以得证。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
struct node{
int a, b, ans;
int id;
}w[N], ans[N];
map<pair<int, int>, int> ma;
bool st[N];
int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0};
int main()
{
int n; cin >> n;
for(int i = 1; i <= n; i ++ )
{
int a, b;
cin >> a >> b;
w[i].a = a, w[i].b = b;
ma[{a, b}] = i;
}
queue<int> q;
for(int i = 1; i <= n; i ++ ){
int a = w[i].a, b = w[i].b;
for(int j = 0; j < 4; j ++ ){
int da = a + dx[j], db = b + dy[j];
if(!ma.count({da, db}) ){
// cout << "st" << i << ' ' << da << ' '<< db << endl;
ans[ma[{a, b}]].a = da, ans[ma[{a, b}]].b = db;
q.push(ma[{a, b}]);
st[i] = true;
break;
}
}
}
while(q.size())
{
auto t = q.front(); q.pop();
int a = w[t].a, b = w[t].b;
for(int i = 0; i < 4; i ++ ){
int x = a + dx[i], y = b + dy[i];
if(ma.count({x, y}) && !st[ma[{x, y}]]){
// cout << a << ' ' << b << ' ' << x << ' ' << y << endl;
ans[ma[{x, y}]] = ans[t];
q.push(ma[{x, y}]);
st[ma[{x,y}]] = true;
}
}
}
for(int i = 1; i <= n; i ++ ){
cout << ans[i].a << ' ' << ans[i].b << endl;
}
return 0;
}