比赛链接:

https://codeforces.com/contest/1651

D. Nearest Excluded Points

题目大意:

在平面上有 \(n\) 个不同的点,这些点在一个集合中,输出离集合中每一个点最近的不在集合中的点,距离以曼哈顿距离计算。

思路:

先从集合中的点中找出周围(上下左右)有不在集合中的点,可以将这些点理解为在集合的边缘的点,离这些点最近的不在集合中的点就是它们周围的一个点。
然后以这些点展开搜索,通过 \(bfs\),逐步向内部推进,更新集合中的点,直到更新完全部点。可以用 \(map\) 储存每一个点最近的那个点。

代码:

#include <bits/stdc++.h>
using namespace std;
#define IOS() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fi first
#define se second
#define pii pair<int, int>
#define all(x) (x).begin(), (x).end()
int n, dx[] = {-1, 0, 1, 0}, dy[] = {0, -1, 0, 1};
int main(){
	IOS();
	cin >> n;
	vector <pii> p(n);
	for (int i = 0; i < n; ++ i)
		cin >> p[i].fi >> p[i].se;
	queue <pii> q;
	map <pii, pii> ans;
	set <pii> s(all(p));
	for (int i = 0; i < n; ++ i){
		int x = p[i].fi, y = p[i].se;
		for (int j = 0; j < 4; ++ j){
			int nx = x + dx[j], ny = y + dy[j];
			if (s.count({nx, ny})) continue;
			q.push({x, y});
			ans[{x, y}] = {nx, ny};
			break;
		}
	}
	while (q.size()){
		pii nd = q.front();
		q.pop();
		int x = nd.fi, y = nd.se;
		for (int i = 0; i < 4; ++ i){
			int nx = x + dx[i], ny = y + dy[i];
			if (!s.count({nx, ny}) || ans.count({nx, ny})) continue;
			ans[{nx, ny}] = ans[{x, y}];
			q.push({nx, ny});
		}
	}
	for (auto &x : p){
		auto t = ans[x];
		cout << t.fi << " " << t.se << "\n";
	}
	return 0;
}
posted on 2022-03-14 00:12  Hamine  阅读(39)  评论(0编辑  收藏  举报