题目大意
在一个二维的牧场中,Farmer John的N(3<=N<=50000)头牛都各占一席。他想用边平行于x轴和y轴的矩形围栏围住所有牛,并且要让围栏尽可能小(牛可以在边界线上)。
不幸地,由于Farmer John的奶牛产量惨淡,导致最后一个季度预算紧张。因此,他希望封闭一个较小的地区来减少维修的费用,他能看到的唯一方法就是修建两个围栏而不是建一个。请编程告诉他用两个围栏比用一个围栏总共能够节省多少需要围住的面积。同样地,用两个围栏的时候必须围住所有的牛(牛同样可以在边界上),边也要平行于x轴和y轴。两个围栏不允许重叠(边界也不能)。注意面积为零是合法的,例如一个围栏有着长度为零的宽或长度为零的长(一条线)。
题目分析
明显地,我们只需要先预处理出 每个点上下的最大与最小的横坐标 与 每个点左右最大与最小的纵坐标。
然后对每个点扫一遍,计算一下以这个点 左右分 & 上下分 所得的面积,取个min就行。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int MAXN=5e4+10; 5 const ll Inf=1e18+7; 6 struct Node{ 7 ll x,y; 8 }a[MAXN],b[MAXN]; 9 10 int n; 11 ll ans1,ans2; 12 inline bool cmpx(Node a,Node b){ 13 return a.x<b.x; 14 } 15 inline bool cmpy(Node a,Node b){ 16 return a.y<b.y; 17 } 18 19 ll amaxy_l[MAXN],aminy_l[MAXN],amaxy_r[MAXN],aminy_r[MAXN]; 20 ll bminx_u[MAXN],bmaxx_u[MAXN],bmaxx_d[MAXN],bminx_d[MAXN]; 21 int main(){ 22 scanf("%d",&n); 23 for(int i=1;i<=n;++i){ 24 scanf("%lld%lld",&a[i].x,&a[i].y); 25 b[i]=a[i]; 26 } 27 sort(a+1,a+n+1,cmpx); 28 sort(b+1,b+n+1,cmpy); 29 30 aminy_l[0]=0x7fffffff;bminx_d[0]=0x7fffffff; 31 for(int i=1;i<=n;++i){ 32 aminy_l[i]=min(aminy_l[i-1],a[i].y);amaxy_l[i]=max(amaxy_l[i-1],a[i].y); 33 bminx_d[i]=min(bminx_d[i-1],b[i].x);bmaxx_d[i]=max(bmaxx_d[i-1],b[i].x); 34 } 35 36 aminy_r[n+1]=0x7fffffffffff;bminx_u[n+1]=0x7fffffffffff; 37 for(int i=n;i>=1;--i){ 38 aminy_r[i]=min(aminy_r[i+1],a[i].y);amaxy_r[i]=max(amaxy_r[i+1],a[i].y); 39 bminx_u[i]=min(bminx_u[i+1],b[i].x);bmaxx_u[i]=max(bmaxx_u[i+1],b[i].x); 40 } 41 42 ll ee=a[n].x,ww=a[1].x,nn=b[n].y,ss=b[1].y; 43 ans1=(nn-ss)*(ee-ww); 44 ans2=0x7fffffffffffffff; 45 for(int i=1;i<n;++i){ 46 ll ta=(a[i].x-ww)*(amaxy_l[i]-aminy_l[i])+(ee-a[i+1].x)*(amaxy_r[i+1]-aminy_r[i+1]); 47 ll tb=(nn-b[i].y)*(bmaxx_u[i]-bminx_u[i])+(b[i-1].y-ss)*(bmaxx_d[i-1]-bminx_d[i-1]); 48 ans2=min(ans2,min(ta,tb)); 49 } 50 printf("%lld ",ans1-ans2); 51 return 0; 52 }