矩形面积 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 }