题目大意: 给你n个点求最小矩形覆盖。
思路:枚举凸包上的边然后,旋转卡壳找三个相应的为止把矩形的四个点求出来。
1 #include<bits/stdc++.h> 2 #define LL long long 3 #define fi first 4 #define se second 5 #define mk make_pair 6 #define pii pair<int,int> 7 #define piii pair<int, pair<int,int>> 8 9 using namespace std; 10 11 const int N=1e5 + 7; 12 const int M=1e4 + 7; 13 const int inf = 0x3f3f3f3f; 14 const LL INF = 0x3f3f3f3f3f3f3f3f; 15 const int mod = 1e9 + 7; 16 const double eps = 1e-10; 17 const double PI = acos(-1); 18 19 int n, cnt; 20 21 int dcmp(double x) { 22 if(fabs(x) < eps) return 0; 23 else return x < 0 ? -1 : 1; 24 } 25 26 struct Point { 27 double x, y; 28 Point(double x = 0, double y = 0) : x(x), y(y) { } 29 30 }p[N], ch[N]; 31 32 typedef Point Vector; 33 34 Point operator + (Vector A, Vector B) {return Point(A.x + B.x, A.y + B.y);} 35 Point operator - (Vector A, Vector B) {return Point(A.x - B.x, A.y - B.y);} 36 Point operator * (Vector A, double p) {return Point(A.x * p, A.y * p);} 37 Point operator / (Vector A, double p) {return Point(A.x / p, A.y / p);} 38 bool operator < (const Vector &A, const Vector &B) {return A.y < B.y || (A.y == B.y && A.x < B.x);} 39 bool operator == (const Vector &A, const Point &B) {return dcmp(A.x - B.x) == 0 && dcmp(A.y - B.y) == 0;} 40 double Dot(Vector A, Vector B) {return A.x * B.x + A.y * B.y;} 41 double Length(Vector A) {return sqrt(Dot(A, A));} 42 double Angle(Vector A, Vector B) {return acos(Dot(A, B) / Length(A) / Length(B));} 43 double Cross(Vector A, Vector B) {return A.x * B.y - A.y * B.x;} 44 double Area2(Point A, Point B, Point C) {return Cross(B - A, C - A);} 45 46 Vector Rotate(Vector A, double rad) { 47 return Vector(A.x * cos(rad) - A.y * sin(rad), A.x * sin(rad) + A.y * cos(rad)); 48 } 49 50 Point GetLineIntersection(Point P, Vector v, Point Q, Vector w) { 51 Vector u = P - Q; 52 double t = Cross(w, u) / Cross(v, w); 53 return P + v * t; 54 } 55 56 double dis(Point A, Point B) { 57 return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y)); 58 } 59 int ConvexHull(Point *p, int n, Point *ch) { 60 sort(p, p + n); 61 int m = 0; 62 for(int i = 0; i < n; i++) { 63 while(m > 1 && dcmp(Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2])) <= 0) m--; 64 ch[m++] = p[i]; 65 } 66 67 int k = m; 68 for(int i = n - 2; i >= 0; i--) { 69 while(m > k && dcmp(Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2])) <= 0) m--; 70 ch[m++] = p[i]; 71 } 72 return m; 73 } 74 75 Point vec[10], vec2[10]; 76 77 int main() { 78 scanf("%d", &n); 79 for(int i = 0; i < n; i++) 80 scanf("%lf%lf", &p[i].x, &p[i].y); 81 cnt = ConvexHull(p, n, ch); 82 83 cnt--; 84 for(int i = 0; i < cnt; i++) { 85 ch[cnt + i] = ch[i]; 86 } 87 88 int pos1 = 1, pos2 = 1, pos3 = 1; 89 double ans = inf; 90 for(int i = 0; i < cnt; i++) { 91 while(abs(Cross(ch[i] - ch[pos1 + 1], ch[i + 1] - ch[pos1 + 1])) > abs(Cross(ch[i] - ch[pos1], ch[i + 1] - ch[pos1]))) 92 pos1++; 93 while(Dot(ch[i + 1] - ch[i], ch[pos2 + 1] - ch[i]) > Dot(ch[i + 1] - ch[i], ch[pos2] - ch[i])) 94 pos2++; 95 pos3 = max(pos3, pos1); 96 while(Dot(ch[i + 1] - ch[i], ch[pos3 + 1] - ch[i]) < Dot(ch[i + 1] - ch[i], ch[pos3] - ch[i])) 97 pos3++; 98 Vector k1 = ch[i + 1] - ch[i]; 99 Vector k2 = Rotate(k1, PI / 2); 100 Point p1 = GetLineIntersection(ch[i], k1, ch[pos2], k2); 101 Point p2 = GetLineIntersection(ch[i], k1, ch[pos3], k2); 102 Point p3 = GetLineIntersection(ch[pos1], k1, ch[pos2], k2); 103 Point p4 = GetLineIntersection(ch[pos1], k1, ch[pos3], k2); 104 double ret = dis(p1, p2) * dis(p1, p3); 105 if(ret < ans) { 106 ans = ret; 107 vec[0] = p1; 108 vec[1] = p2; 109 vec[2] = p3; 110 vec[3] = p4; 111 } 112 } 113 114 ConvexHull(vec, 4, vec2); 115 printf("%.5f ", ans); 116 for(int i = 0; i < 4; i++) { 117 printf("%.5f %.5f ", vec2[i].x, vec2[i].y); 118 } 119 return 0; 120 } 121 /* 122 */