题目描述
随着改革开放的深入推进…… 小T家要拆迁了…… 当对未来生活充满美好憧憬的小T看到拆迁协议书的时候,小T从一位大好的社会主义青年变成了绝望的钉子户。 由于小T的家位于市中心,拆迁工作又难以进行,有关部门决定先把小T家用围栏围起来,以免影响市容。考虑到要建设资源节约型社会,他们希望所用的围栏长度越短越好,由于市中心寸土寸金,在围栏长度最短的情况下,围出的多边形面积越小越好。 为了简化问题,我们约定,小T的家是一个多边形,并且每条边与坐标轴平行,围栏构成的也是多边形,每条边与坐标轴平行。
输入格式
在第一行列出整数n——多边形的顶点的数量。在以下n行中的每一行都有两个整数——沿逆时针方向走过这个多边形顺次所经过的顶点的坐标。边界的任意三个连续顶点不在一条直线上。多边形的边界不含自交和自切。
输出格式
输出两行,第一行为围栏最短的长度,第二行为长度最短的前提下,最小的面积。
【数据范围】
对于100%的数据4≤n≤100000,坐标的绝对值不超过109 。
-
题解
- 可能和凸包没有什么关系吧。。。。。
- 周长显然,直接将所有框起来即可,$2 * (max \{ x_{i} \} - min\{ x_{i} \} \ \ + \ \ max \{ y_{i} \} - min\{ y_{i} \}) $
- 将所有都框起来并不是面积最小,因为有些部分收进去周长不会边长,但是面积会减小;
- 但是也不能全部收进去因为会有类似于“凹”字的形状收进去后周长会变大;
- 考虑每次从上到下扫描,维护当前横坐标的最大值和最小值,如果更新了最大值或最小值就新建一个拐点和新点;
- 再从下面来一次,直接得到了点数O(2*n)的框,求面积即可;
1 #include<bits/stdc++.h> 2 #define inf 0x7fffffff 3 #define ll long long 4 using namespace std; 5 const int N = 200010; 6 int n,c1,c2,c3,c4; 7 struct P{ 8 int x,y; 9 P(int X=0,int Y=0):x(X),y(Y){}; 10 bool operator <(const P&a)const{return x<a.x;} 11 }p[N],p1[N],p2[N],p3[N],p4[N]; 12 char gc(){ 13 static char*P1,*P2,s[1000000]; 14 if(P1==P2)P2=(P1=s)+fread(s,1,1000000,stdin); 15 return(P1==P2)?EOF:*P1++; 16 } 17 int rd(){ 18 int x=0,f=1;char c=gc(); 19 while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();} 20 while(c>='0'&&c<='9')x=x*10+c-'0',c=gc(); 21 return x*f; 22 } 23 ll crs(const P&a,const P&b){return (ll)a.x*b.y-(ll)a.y*b.x;} 24 int main(){ 25 #ifndef ONLINE_JUDGE 26 freopen("bzoj2146.in","r",stdin); 27 freopen("bzoj2146.out","w",stdout); 28 #endif 29 n=rd(); 30 for(int i=1;i<=n;++i)p[i].x=rd(),p[i].y=rd(); 31 sort(p+1,p+n+1); 32 for(int i=1,j=1,mn=inf,mx=-inf;i<=n;i=j){ 33 int mn1=inf,mx1=-inf; 34 for(;j<=n&&p[j].x==p[i].x;j++){ 35 mn1=min(mn1,p[j].y); 36 mx1=max(mx1,p[j].y); 37 } 38 if(mn1<mn){ 39 if(mn!=inf)p1[++c1]=P(p[i].x,mn); 40 p1[++c1]=P(p[i].x,mn=mn1); 41 } 42 if(mx1>mx){ 43 if(mx!=-inf)p2[++c2]=P(p[i].x,mx); 44 p2[++c2]=P(p[i].x,mx=mx1); 45 } 46 } 47 48 for(int i=n,j=n,mn=inf,mx=-inf;i;i=j){ 49 int mn1=inf,mx1=-inf; 50 for(;j&&p[j].x==p[i].x;j--){ 51 mn1=min(mn1,p[j].y); 52 mx1=max(mx1,p[j].y); 53 } 54 if(mn1<mn){ 55 if(mn!=inf)p3[++c3]=P(p[i].x,mn); 56 p3[++c3]=P(p[i].x,mn=mn1); 57 } 58 if(mx1>mx){ 59 if(mx!=-inf)p4[++c4]=P(p[i].x,mx); 60 p4[++c4]=P(p[i].x,mx=mx1); 61 } 62 } 63 P lst = p2[1]; 64 ll ans1=0,ans2=0; 65 for(int i=1;i<=c1;++i){ 66 ans1+=abs(p1[i].x-lst.x)+abs(p1[i].y-lst.y); 67 ans2+=crs(lst,p1[i]); 68 lst=p1[i]; 69 } 70 for(int i=c3;i;--i){ 71 ans1+=abs(p3[i].x-lst.x)+abs(p3[i].y-lst.y); 72 ans2+=crs(lst,p3[i]); 73 lst=p3[i]; 74 } 75 for(int i=1;i<=c4;++i){ 76 ans1+=abs(p4[i].x-lst.x)+abs(p4[i].y-lst.y); 77 ans2+=crs(lst,p4[i]); 78 lst=p4[i]; 79 } 80 for(int i=c2;i;--i){ 81 ans1+=abs(p2[i].x-lst.x)+abs(p2[i].y-lst.y); 82 ans2+=crs(lst,p2[i]); 83 lst=p2[i]; 84 } 85 printf("%lld\n%lld\n",ans1,ans2>>1); 86 return 0; 87 }