矩形面积 HDU - 5251 (旋转卡壳)

矩形面积

HDU - 5251

题意:求能覆盖凸包的最小矩形面积.

旋转卡壳~

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const double eps = 1e-8;
 4 const int inf = 0x3f3f3f3f;
 5 const int maxn = 4010;
 6 
 7 struct Point{
 8     double x, y;
 9     Point(double x = 0, double y = 0): x(x), y(y){}
10 };
11 typedef Point Vector;
12 
13 Vector operator - (Point a, Point b) {
14     return Vector(a.x - b.x, a.y - b.y);
15 }
16 Vector operator + (Vector a, Vector b) {
17     return Vector(a.x + b.x, a.y + b.y);
18 }
19 Vector operator * (Vector a, double p) {
20     return Vector(a.x * p, a.y * p);
21 }
22 Vector operator / (Vector a, double p) {
23     return Vector(a.x / p, a.y / p);
24 }
25 bool operator < (Point a, Point b) {
26     return a.x < b.x || a.x == b.x && a.y < b.y;
27 }
28 int dcmp(double x) {
29     if(fabs(x) < eps) return 0;
30     return x < 0 ? -1 : 1;
31 }
32 
33 bool operator == (Point a, Point b) {
34     return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
35 }
36 double Dot(Vector a, Vector b) {
37     return a.x * b.x + a.y * b.y;
38 }
39 double Cross(Vector a, Vector b) {
40     return a.x * b.y - a.y * b.x;
41 }
42 double Length(Vector a) {
43     return sqrt(Dot(a, a));
44 }
45 double Angle(Vector a) {
46     return atan2(a.y, a.x);
47 }
48 
49 int ConvexHull(Point *p, int n, Point *ch) {
50     sort(p, p+n);
51     int m = 0;
52     for(int i = 0; i < n; i++){
53         while(m > 1 && Cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) <= 0) m--;
54         ch[m++] = p[i];
55     }
56     int k = m;
57     for(int i = n-2; i >= 0; i--){
58         while(m > k && Cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) <= 0) m--;
59         ch[m++] = p[i];
60     }
61     if(n > 1) m--;
62     return m;
63 }
64 
65 double RotateCalipers(Point *p, int n){
66     int up = 1, R = 1, L;
67     p[n] = p[0];
68     double ans = inf;
69     for(int i = 0; i < n; i++) {
70         while(Cross(p[i+1] - p[i], p[up] - p[i]) < Cross(p[i+1] - p[i], p[up+1] - p[i])) up = (up+1)%n;
71         while(Dot(p[i+1] - p[i], p[R] - p[i]) < Dot(p[i+1] - p[i], p[R+1] - p[i])) R = (R+1)%n;
72         if(i == 0) L = R;
73         while(Dot(p[i+1] - p[i], p[L] - p[i]) >= Dot(p[i+1] - p[i], p[L+1] - p[i])) L = (L+1)%n;
74         double len = Length(p[i+1] - p[i]);
75         double area = (Cross(p[i+1] - p[i], p[up] - p[i]) / len) * (Dot(p[i+1] - p[i], p[R] - p[i]) / len - Dot(p[i+1] - p[i], p[L] - p[i]) / len);
76         ans = min(ans, area);
77     }
78     return ans;
79 }
80 Point p[maxn], ch[maxn];
81 int main(){
82     //freopen("in.txt", "r", stdin);
83     int kase = 0;
84     int t;
85     scanf("%d", &t);
86     while(t--){
87         int n;
88         scanf("%d", &n);
89         n *= 4;
90         for(int i = 0; i < n; i++) {
91             scanf("%lf %lf", &p[i].x, &p[i].y);
92         }
93         int sz = ConvexHull(p, n, ch);
94         double ans = RotateCalipers(ch, sz);
95         printf("Case #%d:\n%.0lf\n", ++kase, ans);
96     }
97     return 0;
98 }
View Code

 

posted @ 2017-10-19 21:31  yijiull  阅读(251)  评论(0编辑  收藏  举报