1. 程式人生 > 其它 >CF1651D Nearest Excluded Points(BFS)

CF1651D Nearest Excluded Points(BFS)

CF1651D Nearest Excluded Points

解題思路

我們定義一個點的“距離”為它和其對應答案的曼哈頓距離

我們可以非常輕鬆的知道哪些點的距離是 \(1\)。我們以這些點作為起點 BFS。

如果一個點 \(x\) 距離為 \(1\),它的四周有一個點 \(y\) 距離大於 \(1\) 的話,那麼 \(y\) 的距離就為 \(2\)。這是顯然的,只要 \(y\) 匹配這個與 \(x\) 曼哈頓距離為 \(1\) 的點即可。

所以同理,如果一個點 \(x\) 距離為 \(k\),它的四周有一個點 \(y\) 距離大於 \(k\) 的話,那麼 \(y\) 的距離就為 \(k+1\)

也就是說我們可以快樂地 BFS 了。

程式碼

//Don't act like a loser.
//This code is written by huayucaiji
//You can only use the code for studying or finding mistakes
//Or,you'll be punished by Sakyamuni!!!
#include<bits/stdc++.h>
using namespace std;

int read() {
	char ch=getchar();
	int f=1,x=0;
	while(ch<'0'||ch>'9') {
		if(ch=='-')
			f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') {
		x=x*10+ch-'0';
		ch=getchar();
	}
	return f*x;
}
char read_char() {
	char ch=getchar();
	while(!isalpha(ch)) {
		ch=getchar();
	}
	return ch;
}

const int MAXN=2e5+10;
const int dx[]={0,-1,0,1};
const int dy[]={1,0,-1,0};

int n;
bool vis[MAXN];
queue<int> q;
struct point {
	int x,y;
}p[MAXN],ans[MAXN];
long long node(int x,int y) {
	return 1ll*x*MAXN+y;
}
map<long long,int> mp;

void bfs() {
	while(!q.empty()) {
		int i=q.front();
		q.pop();
		for(int k=0;k<4;k++) {
			int nx=p[i].x+dx[k];
			int ny=p[i].y+dy[k];
			
			int idx=mp[node(nx,ny)];
			if(!idx) {
				mp.erase(node(nx,ny));
			}
			else if(!vis[idx]) {
				ans[idx]=ans[i];
				vis[idx]=1;
				q.push(idx);
			} 
		}
	}
}
int main() {
	cin>>n;
	for(int i=1;i<=n;i++) {
		p[i].x=read();
		p[i].y=read();
		mp[node(p[i].x,p[i].y)]=i;
	}
	
	for(int i=1;i<=n;i++) {
		for(int k=0;k<4;k++) {
			int nx=p[i].x+dx[k];
			int ny=p[i].y+dy[k];
			
			if(mp[node(nx,ny)]==0) {
				mp.erase(node(nx,ny));
				ans[i].x=nx;ans[i].y=ny;
				vis[i]=1; 
				q.push(i);
			} 
		}
	}
	bfs();
	
	for(int i=1;i<=n;i++) {
		printf("%d %d\n",ans[i].x,ans[i].y);
	}
	return 0;
}