ABC215 F - Dist Max 2(二分答案)
目录
Description
有 \(n\) 个点,每个点之间的距离为 \(min(|x_i-x_j|,|y_i-y_j|)\),求点与点之间的最大值
State
\(2<=n<=2*10^5\)
\(0<=x_i,y_i<=10^9\)
Input
3
0 3
3 1
4 10
Output
4
Solution
题目还是很巧妙地,知道了用二分就已经解决一半了
由于两点之间的距离 \(min(|x_i-x_j|,|y_i-y_j|)\),所以如果横坐标两点的距离确定后,那么可以排除很多点,只留下 \(|y_i-y_j|<|x_i-x_j|\) 的那些 \(j\) 点
上面的思路提供了一个突破点:距离;
将横坐标升序排列,二分距离记为 \(x\),如果存在 \(j\) 使得 \(|x_j-x_i|>=x\),(\([j,n]\) 上的点都会满足),之后如果有 \(|y_k-y_i|>=x\) (\(k∈[j,n]\)),则 \(x\) 可以被确定为答案
Code
const int N = 1e6 + 5;
int n, m, k, _;
pll a[N];
ll maxx[N];
ll minn[N];
bool check(ll x)
{
int p = 1;
for(int i = 1; i <= n;){
if(a[i].fi - a[p].fi >= x){
if(maxx[i] - a[p].se >= x) return 1;
if(a[p].se - minn[i] >= x) return 1;
p ++;
}
else i ++;
}
return 0;
}
signed main()
{
//IOS;
while(~ sd(n)){
rep(i, 1, n){
sll2(a[i].fi, a[i].se);
}
sort(a + 1, a + 1 + n);
maxx[n] = minn[n] = a[n].se;
for(int i = n - 1; i; i --){
maxx[i] = max(maxx[i + 1], a[i].se);
minn[i] = min(minn[i + 1], a[i].se);
}
ll l = 0, r = 2e9, ans = 0;
while(r >= l){
ll mid = l + r >> 1;
if(check(mid)){
ans = mid;
l = mid + 1;
}
else{
r = mid - 1;
}
}
pll(ans);
}
//PAUSE;
return 0;
}

浙公网安备 33010602011771号