[ABC330F] Minimize Bounding Square
博導yth給的題目。
考慮到直接O(n)不太好做,但確定了正方形的邊長之後可以很方便地計算操作次數,所以我們直接二分正方形的邊長。
現在轉化成 \(n\) 個點用邊長為 \(s\) 的正方形框起來最小的代價。
將 \(x\) 和 \(y\) 分開考慮,假設我們要算 \(x\) 的代價。
設當前最大值為 \(max\),最小值為 \(min\)。
- 如果最大值減最小值都要小於s的話,不用操作,退出
- 否則,正方形放在兩個最值之間最優,代價為 \(max\) - \(min\) - \(s\)。
程式碼:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,x[N],y[N];
long long k;
int check(int s)
{
int cnt=0;
long long ans=0;
while(n-cnt*2>1)
{
cnt++;
if(x[n-cnt+1]-x[cnt]<s)break;
ans+=x[n-cnt+1]-x[cnt]-s;
}
cnt=0;
while(n-cnt*2>1)
{
cnt++;
if(y[n-cnt+1]-y[cnt]<s)break;
ans+=y[n-cnt+1]-y[cnt]-s;
}
return ans<=k;
}
int main()
{
scanf("%d%lld",&n,&k);
for(int i=1;i<=n;i++)scanf("%d%d",&x[i],&y[i]);
sort(x+1,x+1+n),sort(y+1,y+1+n);
int l=0,r=1e9;
while(l<r)
{
int mid=l+r>>1;
if(check(mid))r=mid;
else l=mid+1;
}
printf("%d",l);
return 0;
}