Fork me on GitHub

BZOJ 1069: [SCOI2007]最大土地面积(旋转卡壳)

题目链接~ 

1069: [SCOI2007]最大土地面积

思路很简单,极角排序求完凸包后,在凸包上枚举对角线,然后两边分别来两个点旋转卡壳一下,搞定!

不过计算几何的题目就是这样,程序中间的处理还是比较麻烦的,写的时候要很小心,特别是存点和枚举的时候要注意是个循环。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<algorithm>
  7 
  8 #define For(i,a,b) for(register int i=a;i<=b;++i)
  9 #define Dwn(i,a,b) for(register int i=a;i>=b;--i)
 10 #define Re register
 11 
 12 using namespace std;
 13 
 14 const int N=2005;
 15 
 16 struct P{
 17     double x,y;
 18 }st[N],O,p[N];
 19 int n,top=-1;
 20 
 21 P operator -(P a,P b){
 22     P t; t.x=a.x-b.x; t.y=a.y-b.y; return t;
 23 }
 24 double operator *(P a,P b){
 25     return a.x*b.y-b.x*a.y;
 26 } 
 27 double Dis(P a,P b){
 28     return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );
 29 }
 30 int Xx(P a){
 31     if(a.x-O.x>0 &&a.y-O.y>=0)return 1;
 32     if(a.x-O.x<=0&&a.y-O.y>0 )return 2;
 33     if(a.x-O.x<0 &&a.y-O.y<=0)return 3;
 34     if(a.x-O.x>=0&&a.y-O.y<0 )return 4;
 35 }
 36 bool cmp(const P a,const P b){
 37     int aX=Xx(a);
 38     int bX=Xx(b);
 39     if(aX!=bX)return aX<bX;
 40     double cx= (a-O)*(b-O);
 41     if(cx==0)return a.x<b.x;
 42     else return cx>0;
 43 }
 44 bool cmpY(const P a,const P b){
 45     return a.y<b.y;
 46 }
 47 
 48 void TuBao(){
 49     st[++top]=p[1];
 50     st[++top]=p[2];
 51     For(i,3,n+1){
 52         while( (p[i]-st[top-1])*(st[top]-st[top-1])>=0 ) top--;
 53         st[++top]=p[i];
 54     }
 55 }
 56 
 57 double ans=0;
 58 void SpinStir(){
 59     P p1,p2;
 60     int i1,i2;
 61     For(x,0,top-1){
 62         i1=(x+3)%top; p1=st[i1];
 63         i2=(x+1)%top; p2=st[i2];
 64         For(y,x+2,top-1){
 65             int Ni; P Np;
 66             
 67             Ni=(i1+1)%top; 
 68             Np=st[Ni];
 69             while(Ni!=x&&(Np-st[y])*(st[x]-st[y])>(p1-st[y])*(st[x]-st[y])){
 70                 i1=Ni; p1=Np;     Ni=(i1+1)%top; Np=st[Ni];
 71             } 
 72             
 73             Ni=(i2+1)%top;
 74             Np=st[Ni];
 75             while(Ni!=y&&(Np-st[x])*(st[y]-st[x])>(p2-st[x])*(st[y]-st[x])){
 76                 i2=Ni; p2=Np;    Ni=(i2+1)%top; Np=st[Ni];
 77             }
 78              
 79             double Sm=(p1-st[y])*(st[x]-st[y])/2 + (p2-st[x])*(st[y]-st[x])/2;
 80             ans=max(ans,Sm);
 81         }
 82     }
 83 }
 84 
 85 int main(){
 86     //freopen("ex.in","r",stdin);
 87     
 88     scanf("%d",&n);
 89     For(i,1,n){
 90         scanf("%lf%lf",&p[i].x,&p[i].y);
 91     }
 92     sort(p+1,p+n+1,cmpY);
 93     O=p[1];
 94     sort(p+2,p+n+1,cmp);
 95     p[n+1]=p[1]; 
 96     TuBao(); 
 97     SpinStir();
 98     printf("%.03lf",ans);
 99     return 0;
100     
101 }

 

posted @ 2019-02-02 16:57  H_LAUV  阅读(198)  评论(0编辑  收藏  举报
Live2D //博客园自带,可加可不加