D. Nearest Excluded Points

Educational Codeforces Round 124 (Rated for Div. 2)

D. Nearest Excluded Points

所有的点可以分成两种情况

①.该点上下左右四个位置存在合法的点,合法指的是不出现在题目给的n个点中。

②.该点上下左右四个位置的点都不合法。

对于第一种情况,答案就是周围的任意一个合法 的点,第二种情况答案就是离它最近的一个且周围有合法点的点\(p\)\(p\)的答案就是它的答案。

所以我们可以进行\(BFS\),先把最外围的点(第一种情况的点)加入到队列里面,然后利用队列里面的点\(q\)不断更新上下左右四个方向的点,如果这个点\(p\)在给的\(n\)个点中,就把\(q\)答案赋给\(p\),然后把\(p\)加入到队列里面继续更新其他的点,这样能保证所有\(n\)个点都能被更新到最小的合法的答案(证明:第一种的点一定会计算出合法答案, 对第二种点来说, 他的周围上下左右四个方向都有题目给的点,所以我们对队列中每个点进行四个方向 的更新,一定能更新到每个题目中给的点,因为是不断的进行上下左右四个方向的更新,所以答案一定保证是最小的)。

#include <bits/stdc++.h>
#define PII pair<int,int>
#define LL long long
#define fi first
#define debug(x) cout << #x << " = " << x << endl;
#define se second
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define sz(x) (int)x.size()

using namespace std;

const int N = 200010;

struct node{
	int x, y;
}a[N],ans[N];

bool vis[N];
int n;
map<PII,int>mp;
int dx[] = {0, 0, -1, 1}, dy[] = {1, -1, 0, 0};

int main()
{
	cin >> n;
	for(int i = 1; i <= n; i ++ ){
		int x, y;
		scanf("%d %d",&x, &y);
		mp[{x, y}] = i;
		a[i] = {x, y};
	}
	queue<int>q;
	for(int i = 1; i <= n; i ++ ){
		int x = a[i].x, y = a[i].y;
		for(int i = 0; i < 4; i ++ ){
			int nx = x + dx[i], ny = y + dy[i];
			if(!mp.count({nx, ny}) && !vis[mp[{x, y}]]){
				vis[mp[{x, y}]] = true;
				ans[mp[{x, y}]] = {nx, ny};
				// cout << mp[{x, y}] << endl;
				q.push(mp[{x, y}]);
			}
		}
	}
	// debug(q.size());
	while(!q.empty()){
		int t = q.front();
		q.pop();
		int x = a[t].x, y = a[t].y;
		for(int i = 0; i < 4; i ++ ){
			int nx = x + dx[i], ny = y + dy[i];
			int xx = mp[{nx, ny}];
			if(vis[xx] || !mp.count({nx, ny})) continue;
			q.push(xx);
			vis[xx] = true;
			ans[xx] = ans[t];
		}
	}
	for(int i = 1; i <= n; i ++ ){
		cout << ans[i].x << " " << ans[i].y << endl;
	}
	return 0;
}


posted @ 2022-03-11 11:12  合肥学院王星力  阅读(221)  评论(0)    收藏  举报