BZOJ 1069 [SCOI2007]最大土地面积 旋转卡壳
题解:
现在写起旋转卡壳一气呵成~
枚举凸包上每个点i,然后顺时针逐个扫描整个凸包上的点p1,在此同时维护两个指针p2,p3,分别表示在i和p1连线两侧的离这条线最远的点,发现p2,p3是单调的~
总时间复杂度n^2的~
View Code
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <iostream> 6 #include <algorithm> 7 8 #define N 2222 9 #define EPS 1e-7 10 11 using namespace std; 12 13 struct PO 14 { 15 double x,y; 16 void prt() {printf("%lf %lf\n",x,y);} 17 }p[N],stk[N<<1],o; 18 19 int n,top; 20 double ans; 21 22 inline PO operator -(PO a,PO b) 23 { 24 a.x-=b.x; a.y-=b.y; 25 return a; 26 } 27 28 inline int dc(double x) 29 { 30 if(x>EPS) return 1; 31 else if(x<-EPS) return -1; 32 return 0; 33 } 34 35 inline bool cmp(const PO &a,const PO &b) 36 { 37 if(dc(a.x-b.x)==0) return a.y<b.y; 38 return a.x<b.x; 39 } 40 41 inline double cross(PO a,PO b,PO c) 42 { 43 return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y); 44 } 45 46 inline double getangle(const PO &a,const PO &b,const PO &c,const PO &d) 47 { 48 return cross(o,b-a,d-c); 49 } 50 51 inline void read() 52 { 53 scanf("%d",&n); 54 for(int i=1;i<=n;i++) 55 scanf("%lf%lf",&p[i].x,&p[i].y); 56 } 57 58 inline void graham() 59 { 60 sort(p+1,p+1+n,cmp); 61 top=0; 62 for(int i=1;i<=n;i++) 63 { 64 while(top>=2&&dc(cross(stk[top-1],stk[top],p[i]))<=0) top--; 65 stk[++top]=p[i]; 66 } 67 int tmp=top; 68 for(int i=n-1;i>=1;i--) 69 { 70 while(top>=tmp+1&&dc(cross(stk[top-1],stk[top],p[i]))<=0) top--; 71 stk[++top]=p[i]; 72 } 73 } 74 75 inline void rotating_calipers() 76 { 77 for(int i=1;i<top;i++) stk[top+i-1]=stk[i]; 78 for(int i=1;i<top;i++) 79 { 80 int p1=i+1; 81 int p2=p1+1; 82 int p3=p2+1; 83 for(;p2<i+top-1;p2++) 84 { 85 while(1) 86 { 87 double k=getangle(stk[i],stk[p2],stk[p1],stk[p1+1]); 88 if(dc(k)>=0) break; 89 else p1++; 90 } 91 while(1) 92 { 93 double k=getangle(stk[p2],stk[i],stk[p3],stk[p3+1]); 94 if(dc(k)>=0) break; 95 else p3++; 96 if(p3-i>=top-1) break; 97 } 98 if(p3-i>=top-1) break; 99 ans=max(ans,(fabs(cross(stk[i],stk[p1],stk[p2]))+fabs(cross(stk[i],stk[p2],stk[p3])))/2); 100 } 101 } 102 } 103 104 inline void go() 105 { 106 graham(); 107 rotating_calipers(); 108 printf("%.3lf\n",ans); 109 } 110 111 int main() 112 { 113 read(),go(); 114 return 0; 115 }
没有人能阻止我前进的步伐,除了我自己!