老套路了。
用二分求答案,judge时把每个点转换成矩形,最后看n个矩形是否有交点
#include<bits/stdc++.h> using namespace std; #define N 3005 #define ll long long struct Point{ll x,y;}c; struct Rec{ll x1,x2,y1,y2;}rec; ll n,x[N],y[N],h[N]; Rec merge(Rec a,Rec b){ Rec res; res.x1=max(a.x1,b.x1); res.y1=max(a.y1,b.y1); res.x2=min(a.x2,b.x2); res.y2=min(a.y2,b.y2); return res; } int judge(ll H){//金字塔高度为H Rec now; ll d=H-h[1]; now=(Rec){x[1]-d,x[1]+d,y[1]-d,y[1]+d}; for(int i=2;i<=n;i++){ ll d=H-h[i]; Rec t=(Rec){x[i]-d,x[i]+d, y[i]-d,y[i]+d}; now=merge(now,t); if(now.x1>now.x2 || now.y1>now.y2)return 0; } c=(Point){now.x1,now.y1}; return 1; } int main(){ ll L=0,R=1e18,mid,ans; cin>>n; for(int i=1;i<=n;i++) scanf("%lld%lld%lld",&x[i],&y[i],&h[i]),L=max(L,h[i]); while(L<=R){ mid=L+R>>1; if(judge(mid)) ans=mid,R=mid-1; else L=mid+1;; } cout<<c.x<<" "<<c.y<<" "<<ans<<'\n'; } /* 5 3 7 6 1 2 9 3 3 4 6 4 8 12 4 1 */