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;
}