bzoj 2146: Construct

Description

随着改革开放的深入推进…… 小T家要拆迁了…… 当对未来生活充满美好憧憬的小T看到拆迁协议书的时候,小T从一位大好的社会主义青年变成了绝望的钉子户。 由于小T的家位于市中心,拆迁工作又难以进行,有关部门决定先把小T家用围栏围起来,以免影响市容。考虑到要建设资源节约型社会,他们希望所用的围栏长度越短越好,由于市中心寸土寸金,在围栏长度最短的情况下,围出的多边形面积越小越好。 为了简化问题,我们约定,小T的家是一个多边形,并且每条边与坐标轴平行,围栏构成的也是多边形,每条边与坐标轴平行。

Input

在第一行列出整数n——多边形的顶点的数量。在以下n行中的每一行都有两个整数——沿逆时针方向走过这个多边形顺次所经过的顶点的坐标。边界的任意三个连续顶点不在一条直线上。多边形的边界不含自交和自切。

Output

输出两行,第一行为围栏最短的长度,第二行为长度最短的前提下,最小的面积。

Sample Input

8
0 0
9 0
9 9
6 9
6 3
3 3
3 6
0 6

Sample Output

36
63

【数据范围】
对于100%的数据4≤n≤100000,坐标的绝对值不超过109 。

第一眼看过去,咦这不是裸凸包么。写好了后WA了= =
然后发现是在曼哈顿距离下的凸包
然后就写写写。。分左上左下右上右下四个部分分别求边界。每个部分x y都是单调的
结果一直WA
然后要到了数据,发现错了一个点。。就是图中这个。。


然后我发现我的点没排序。。
然后排序后发现周长算不出了,面积对了= =原来是周长对面积错一个点。
正打算要不要两份合起来的时候时候@PoPoQQQ 告诉我,周长直接框个矩形就好了
然后突然就醒悟了
终于A掉了
【可怕的计算几何】
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
struct point
{
     long long x,y;
}a[100001],b[100001],chs[100001];
inline bool cmp1(point x,point y)
{  
     if(x.x<y.x)  
          return true;
     else if(x.x==y.x)  
          if(x.y>y.y)
	           return true;
     return false;  
}
inline bool cmp2(point x,point y)
{  
     if(x.x<y.x)  
          return true;
     else if(x.x==y.x)  
          if(x.y<y.y)
	           return true;
     return false;  
}
inline bool cmp3(point x,point y)
{  
     if(x.x>y.x)  
          return true;
     else if(x.x==y.x)  
          if(x.y<y.y)
	           return true;
     return false;  
}
inline bool cmp4(point x,point y)
{  
     if(x.x>y.x)  
          return true;
     else if(x.x==y.x)  
          if(x.y>y.y)
	           return true;
     return false;  
}
inline long long absx(long long x)
{
     if(x<0)
          x=-x;
     return x;
}
inline long long dis(point x,point y)
{
    return absx(x.x-y.x)+absx(x.y-y.y);
}
int main()
{
//	 freopen("construct.in","r",stdin);
//	 freopen("construct.out","w",stdout);
     int n;
     scanf("%d",&n);
     int i;
     long long minx=2100000000,miny=2100000000,maxx=-2100000000,maxy=-2100000000;
     for(i=1;i<=n;i++)
     {
          scanf("%lld%lld",&a[i].x,&a[i].y);
          minx=min(minx,a[i].x);
          miny=min(miny,a[i].y);
          maxx=max(maxx,a[i].x);
          maxy=max(maxy,a[i].y);
          b[i].x=a[i].x;
          b[i].y=a[i].y;
     }
     long long ans=maxx-minx+maxy-miny;
     ans=ans*(long long)2;
     printf("%lld\n",ans);
     minx=2100000000;
	 miny=2100000000;
     int d;
     for(i=1;i<=n;i++)
     {
          if(a[i].x<minx)
          {
               minx=a[i].x;
               miny=a[i].y;
               d=i;
          }
          else if(a[i].x==minx)
          {
               if(a[i].y<miny)
               {
                    miny=a[i].y;
                    d=i;
               }
          }
     }

     sort(a+1,a+1+n,cmp1);
     
     minx=-2100000000;
	 miny=2100000000;
     for(i=1;i<=n;i++)
     {
          if(a[i].y<miny)
          {
               miny=a[i].y;
               minx=a[i].x;
               d=i;
          }
          else if(a[i].y==miny)
          {
               if(a[i].x>minx)
               {
                    minx=a[i].x;
                    d=i;
               }
          }
     }
     chs[1]=a[1];
     int sp=1,k=2;
     bool flag=0;
     long long xt=a[1].x,yt=a[1].y;
     while(k<=d)
     {
          if(a[k].x>=chs[sp].x&&a[k].y<=chs[sp].y||sp==0)
          {
               sp++;
               chs[sp].x=a[k].x;
               chs[sp].y=a[k].y;
               k++;
          }
          else if(a[k].y>chs[sp].y)
		       k++;
		  else if(sp>1)
               sp--;
          else
               k++;
     }
     
     int st=d;
     i=d;
     int p=0;
     while(p<n)
     {
          p++;
          a[p]=b[i];
          i=i%n+1;
     }
     minx=-2100000000;
	 miny=2100000000;
	 sort(a+1,a+1+n,cmp2);
     for(i=1;i<=n;i++)
     {
          if(a[i].x>minx)
          {
               minx=a[i].x;
               miny=a[i].y;
               d=i;
          }
          else if(a[i].x==minx)
          {
               if(a[i].y<miny)
               {
                    miny=a[i].y;
                    d=i;
               }
          }
     }
     xt=chs[sp].x;
	 yt=chs[sp].y;
	 k=1;
     while(k<=d)
     {
          if(a[k].x>=chs[sp].x&&a[k].y>=chs[sp].y||sp==0)
          {
               sp++;
               chs[sp].x=a[k].x;
               chs[sp].y=a[k].y;
               k++;
          }
          else if(a[k].x<chs[sp].x)
               k++;
          else
               sp--;
     }
     //下边界 
     
    
     sort(a+1,a+1+n,cmp3);
     minx=2100000000;
	 miny=-2100000000;
     for(i=1;i<=n;i++)
     {
          if(a[i].y>miny)
          {
               miny=a[i].y;
               minx=a[i].x;
               d=i;
          }
          else if(a[i].y==miny)
          {
               if(a[i].x>minx)
               {
                    minx=a[i].x;
                    d=i;
               }
          }
     }
     xt=chs[sp].x;
	 yt=chs[sp].y;
	 k=1;
     while(k<=d)
     {
          if(a[k].x<=chs[sp].x&&a[k].y>=chs[sp].y||sp==0)
          {
               sp++;
               chs[sp].x=a[k].x;
               chs[sp].y=a[k].y;
               k++;
          }
          else if(a[k].y<chs[sp].y)
               k++; 
          else
               sp--;
     }
     //右边界 
     
     sort(a+1,a+1+n,cmp4);
     minx=2100000000;
	 miny=-2100000000;
     for(i=2;i<=n;i++)
     {
          if(a[i].x<minx)
          {
               minx=a[i].x;
               miny=a[i].y;
               d=i;
          }
          else if(a[i].x==minx)
          {
               if(a[i].y<=miny)
               {
                    miny=a[i].y;
                    d=i;
               }
          }
     }
     xt=chs[sp].x;
	 yt=chs[sp].y;
	 k=1;
     while(k<=d)
     {
          if(a[k].x<=chs[sp].x&&a[k].y<=chs[sp].y||sp==0)
          {
               sp++;
               chs[sp].x=a[k].x;
               chs[sp].y=a[k].y;
               k++;
          }
          else if(a[k].x>chs[sp].x)
               k++; 
          else
               sp--;
     }
     //上边界 左边界 
     
     
     
     
     /*long long ans=0;
     for(i=1;i<=sp-1;i++)
          ans+=dis(chs[i],chs[i+1]);
     ans+=dis(chs[1],chs[sp]);
     printf("%lld\n",ans);*/
     ans=0;
     xt=chs[1].x;
	 yt=chs[1].y;
	 long long lx=0;
     for(i=2;i<=sp;i++)
     {
          if(chs[i].x!=xt&&chs[i].y!=yt)
          {
               long long dx=chs[i].x-xt;
               long long dy=chs[i].y-yt;
               i--;
          	   if(dx>0&&dy>0)
			   {
			        chs[i].x=xt;
			        chs[i].y=chs[i+1].y;
			   }
			   else if(dx>0)
			   {
			        chs[i].x=chs[i+1].x;
			        chs[i].y=yt;
			   }
			   else if(dy>0)
			   {
			        chs[i].x=chs[i+1].x;
			        chs[i].y=yt;
			   }
			   else
			   {
			        chs[i].x=xt;
			        chs[i].y=chs[i+1].y;
			   }
			   i--;
          }
          else if(chs[i].x!=xt)
          {
          	   long long dx=chs[i].x-xt;
			   lx+=dx;
               xt=chs[i].x;
          }
          else if(chs[i].y!=yt)
          {
          	   long long dy=chs[i].y-yt;
   	           ans+=dy*lx;
               yt=chs[i].y;
          }
     }
     printf("%lld\n",ans);
     return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值