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 }