已知平面上n个不同的点。第i个点的坐标为(æi, yi)。对于每个点i,找到在给定的n个点中最近的整数坐标点(以曼哈顿距离为单位)。如果有多个这样的点,你可以选择其中任何一个。两点(21,91)和(22,92)之间的曼哈顿距离为21 - 22l + ly1 - 92l输入输入的第一行包含一个整数n (1 < n < 2·105)-集合中的点的数量。下面的n条线描述点。第i个包含两个整数æ;和y;(1 S 2i, yi < 2 - 105) -第i个点的坐标。它保证输入中的所有点都是不同的。输出打印n行。在第i行中,打印一个整数坐标的点,它不在给定的n个点中,并且是距离输入的第i个点最近的点(根据曼哈顿距离)。输出坐标应该在范围[-10;10°)。可以证明,任何最优答案都满足这些约束条件。如果有几个答案,您可以打印其中任何一个。
Examples
input
Copy
6 2 2 1 2 2 1 3 2 2 3 5 5
output
Copy
1 1 1 1 2 0 3 1 2 4 5 4
input
Copy
8 4 4 2 4 2 2 2 3 1 4 4 2 1 3 3 3
output
Copy
4 3 2 5 2 1 2 5 1 5 4 1 1 2 3 2
题解:
1.如果一个点的四周如果有一个点没有点,那么这个点就是离他最近的,这种情况比较好想,
2.那么对于四周都有点包围的点呢,答案应该为从最外层,到他最近的点
换而言之,答案应该包含在我们由1求的点中,不断向内部bfs,只遍历题中出现过的点,
具体细节,代码中有注释
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<set>
using namespace std;
#define int long long
const int N = 4e5 + 10;
typedef pair<int, int> PII;
int n,k;
int dx[4] = {0,-1,0,1};
int dy[4] = {-1,0,1,0};
void solve()
{
cin >> n;
vector <PII> a(n);
for(int i = 0;i < n;i++)
{
int x,y;
cin >> x >> y;
a[i] = {x,y};;
}
set <PII> st(a.begin(),a.end());
map<PII,PII> ans;
queue<PII> q;
for(int i = 0;i < n;i++)
{
for(int j = 0;j < 4;j++)
{
int tx = a[i].first + dx[j];
int ty = a[i].second + dy[j];
if(st.count({tx,ty}))
{
continue;
}
ans[{a[i].first,a[i].second}] = {tx,ty};
q.push({a[i].first,a[i].second});//把已经求出答案的点存进队列,与他们代表点集合的最外层
break;
}
}
while(q.size())
{
PII t = q.front();
q.pop();
for(int i = 0;i < 4;i++)
{
int tx = t.first + dx[i];
int ty = t.second + dy[i];
if(ans.count({tx,ty}) || !st.count({tx,ty}))
{
//st代表如果遍历过程中超出规定范围要停下,因为点集内部被包围的点,四周肯定是被标记过的,没被标记,肯定是跑歪了
//ans代表此时走到的点,在之前已经出现过了,既然是第二次遍历,那么点肯定不是最近的
continue;
}
ans[{tx,ty}] = ans[{t.first,t.second}];//由上一个点的状态转移过来,递归下来,答案为最外层某个点存的答案
q.push({tx,ty});
}
}
for(int i = 0;i < n;i++)
{
cout <<ans[a[i]].first <<" "<<ans[a[i]].second<<"\n";
}
}
//1 2 4
signed main()
{
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
int t = 1;
// cin >> t;
//scanf("%lld",&t);
while (t--)
{
solve();
}
}
//1 1 1 0 1
//1 1 1 0 1
//1 1 1 0 1
//1 1 1 0 1
//0 1 1 1 1
//0 1 1 1 1