题目
题意:给定
n
n
n个整数点
x
i
,
y
i
(
1
<
=
x
i
,
y
i
<
=
2
∗
1
0
5
)
x_i,y_i(1<=x_i,y_i<=2*10^5)
xi,yi(1<=xi,yi<=2∗105),现在求出每个点对应的最近点(曼哈顿距离),要求这些最近点不能在这
n
n
n个点中。
思路:直接暴搜,会T到家。
换个思路,对于这
n
n
n个点(便于区分,称它们为有效点),我们发现,对于有效点
x
x
x,除非周围都被其他有效点包围,否则它的exclueded point只要取它周边的相连的非有效点即可,此时距离最小。
那么对于剩下那些被其他有效点包围的 有效点,我们怎么求它的exclueded point呢?我们bfs搜索它四周的有效点即可。
通过这种方式,bfs搜索的范围被限制在相邻的点中,搜索范围就得到限制了。
代码
#include<bits/stdc++.h>
using namespace std;
int dx[] = {0, 0, -1, 1};
int dy[] = {-1, 1, 0, 0};
int main() {
int n;
scanf("%d", &n);
vector<pair<int, int>> a(n);
for (auto &v : a) scanf("%d %d", &v.first, &v.second);
set<pair<int, int>> st(a.begin(), a.end());
map<pair<int, int>, pair<int, int>> ans;
queue<pair<int, int>> q;
for (auto v : a) {
int x = v.first, y = v.second;
for (int i = 0; i < 4; ++i) {
int nx = x + dx[i], ny = y + dy[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 + dx[i], ny = y + dy[i];
if (!st.count({nx, ny}) || ans.count({nx, ny})) {
continue;
}
ans[{nx, ny}] = ans[{x, y}];
q.push({nx, ny});
}
}
for (auto v : a) {
auto it = ans[{v.first, v.second}];
printf("%d %d\n", it.first, it.second);
}
return 0;
}