[ABC330F] Minimize Bounding Square

DLYdly1105發表於2024-10-09

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

相關文章