hdu 3934 Summer holiday (凸包+旋转卡壳)
晚上为了演示给师弟看水平序的凸包是多么的好写,于是就随便找了一题凸包,25min居然1y掉了。。
代码如下:
1 #include <cmath> 2 #include <cstdio> 3 #include <iostream> 4 #include <cstring> 5 #include <algorithm> 6 7 using namespace std; 8 9 const int N = 1111111; 10 const double EPS = 1e-8; 11 inline int sgn(double x) { return (x > EPS) - (x < -EPS);} 12 struct Point { 13 double x, y; 14 Point() {} 15 Point(double x, double y) : x(x), y(y) {} 16 Point operator - (Point a) { return Point(x - a.x, y - a.y);} 17 bool operator < (Point a) const { return sgn(x - a.x) < 0 || sgn(x - a.x) == 0 && y < a.y;} 18 } ; 19 20 inline double cross(Point a, Point b) { return a.x * b.y - a.y * b.x;} 21 22 int andrew(Point *pt, Point *ch, int n) { 23 sort(pt, pt + n); 24 int m = 0; 25 for (int i = 0; i < n; i++) { 26 while (m > 1 && sgn(cross(pt[i] - ch[m - 2], ch[m - 1] - ch[m - 2])) <= 0) m--; 27 ch[m++] = pt[i]; 28 } 29 int k = m; 30 for (int i = n - 2; i >= 0; i--) { 31 while (m > k && sgn(cross(pt[i] - ch[m - 2], ch[m - 1] - ch[m - 2])) <= 0) m--; 32 ch[m++] = pt[i]; 33 } 34 if (n > 1) m--; 35 return m; 36 } 37 38 Point ch[N], pt[N]; 39 inline double area(Point a, Point b, Point c) { return fabs(cross(c - a, b - a));} 40 41 double work(Point *pt, int n) { 42 if (n < 3) return 0; 43 double ans = area(pt[0], pt[1], pt[2]); 44 for (int i = 0, j = 1, k = 2; i < n; i++) { 45 while (true) { 46 bool df = false; 47 if (i == j) j = (j + 1) % n; 48 if (j == k) k = (k + 1) % n; 49 while (true) { 50 double a1 = area(pt[i], pt[j], pt[k]); 51 double a2 = area(pt[i], pt[j], pt[(k + 1) % n]); 52 ans = max(ans, a1); 53 if (sgn(a1 - a2) > 0) break; 54 k = (k + 1) % n; 55 df = true; 56 } 57 while (true) { 58 double a1 = area(pt[i], pt[j], pt[k]); 59 double a2 = area(pt[i], pt[(j + 1) % n], pt[k % n]); 60 ans = max(ans, a1); 61 if (sgn(a1 - a2) > 0) break; 62 j = (j + 1) % n; 63 df = true; 64 } 65 if (!df) break; 66 } 67 } 68 return ans / 2; 69 } 70 71 int main() { 72 int n; 73 while (~scanf("%d", &n)) { 74 for (int i = 0; i < n; i++) scanf("%lf%lf", &pt[i].x, &pt[i].y); 75 n = andrew(pt, ch, n); 76 printf("%.2f\n", work(ch, n)); 77 } 78 return 0; 79 }
——written by Lyon