bzoj 1069 [SCOI2007]最大土地面积
看了黄学长的博客才知道是旋转卡壳的裸题,我似乎是用暴力卡过的
首先这四个点一定在凸包上,要先把凸包搞出来(忘了判重点WA了一个小时QAQ),
因为n的范围很小,所以我们可以直接枚举这个四边形的对角线,分别找这条对角线两边的点与这条线组成的最大三角形
因为是一个凸包所以我们可以三分,但实际上这是有决策单调性的,所以直接上旋转卡壳就可以过了
1 #define MAXN 4010UL 2 #include <cstdio> 3 #include <cmath> 4 #include <algorithm> 5 6 using namespace std; 7 8 int n, hd, tl, T, num; 9 double ans; 10 11 struct Point { 12 double x, y; 13 friend double operator * (Point a, Point b) { 14 return a.x*b.y-a.y*b.x; 15 } 16 friend Point operator - (Point a, Point b) { 17 return (Point){a.x-b.x, a.y-b.y}; 18 } 19 friend bool operator < (Point a, Point b) { 20 return a.x==b.x?a.y<b.y:a.x<b.x; 21 } 22 }pt[MAXN<<1], q[MAXN<<1]; 23 24 bool Check(Point a, Point b) { 25 return a*b<=0; 26 } 27 28 double F(Point a, Point b, Point c) { 29 30 return fabs(a*b+b*c+c*a)/2.; 31 } 32 33 int Solve(Point a, Point b, int l, int r) { 34 ++ num; 35 double ret = -1.; 36 int pos; 37 while(r-l>=3) {++ T; 38 int mid = (l+r)>>1, midd = (mid+r)>>1; 39 if(F(a, b, pt[mid])>F(a, b, pt[midd])) r = midd-1; 40 else l = mid+1; 41 } 42 for(int i = l ; i <= r ; ++ i) { 43 double w = F(a, b, pt[i]); 44 if(ret<w) ret = w, pos = i; 45 } 46 return pos; 47 } 48 49 int main() { 50 scanf("%d", &n); 51 for(int i = 1 ; i <= n ; ++ i) scanf("%lf%lf", &pt[i].x, &pt[i].y); 52 sort(pt+1, pt+n+1); 53 for(int i = 1 ; i <= n ; ++ i) { 54 while(hd+1<tl&&Check(q[tl-1]-q[tl-2], pt[i]-q[tl-1])) -- tl; 55 q[tl ++] = pt[i]; 56 } 57 for(int i = n-1 ; i >= 2 ; -- i) { 58 while(hd+1<tl&&Check(q[tl-1]-q[tl-2], pt[i]-q[tl-1])) -- tl; 59 q[tl ++] = pt[i]; 60 } 61 while(hd+1<tl&&Check(q[tl-1]-q[tl-2], q[hd]-q[tl-1])) -- tl; 62 int ti = 0; 63 for(int i = hd ; i < tl ; ++ i) ++ ti, pt[ti] = q[i], pt[ti+tl-hd] = q[i]; 64 for(int i = 1 ; i <= ti ; ++ i) { 65 int lt1 = 0, lt2 = 0; 66 for(int j = i+2 ; j <= ti ; ++ j) if(j-i>=2&&i+ti-j>=2) { 67 lt1 = Solve(pt[i], pt[j], i+1, j-1), lt2 = Solve(pt[i], pt[j], j+1, i+ti-1); 68 double w = F(pt[i], pt[j], pt[lt1])+F(pt[i], pt[j], pt[lt2]); 69 if(ans<w) ans = w; 70 } 71 } 72 printf("%.3lf", ans); 73 return 0; 74 }