首页 > 代码库 > BZOJ1185 [HNOI2007]最小矩形覆盖
BZOJ1185 [HNOI2007]最小矩形覆盖
一道计算几何裸题。。。调了蒟蒻两个小时。。。
问题出在求dis的时候忘了sqrt了,好了你现在可以退役滚蛋了,简直侮辱我们搞OI的人的智商
首先求个凸包出来,矩形的一边一定和凸包上一边重合。
然后枚举凸包上的边,用三个点同时旋转卡壳,卡出最小的矩形。
这题目写的我。。。醉了
1 /************************************************************** 2 Problem: 1185 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:180 ms 7 Memory:2372 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cmath> 12 #include <algorithm> 13 14 #define P Point 15 using namespace std; 16 typedef double lf; 17 const int N = 50005; 18 const lf eps = 1e-8; 19 20 struct Point { 21 lf x, y; 22 P() {} 23 P(lf _x, lf _y) : x(_x), y(_y) {} 24 25 inline bool operator < (const P &X) const { 26 return fabs(y - X.y) < eps ? x < X.x : y < X.y; 27 } 28 inline bool operator == (const P &X) const { 29 return fabs(x - X.x) < eps && fabs(y - X.y) < eps; 30 } 31 inline bool operator != (const P &X) const { 32 return !(*this == X); 33 } 34 inline P operator + (const P &X) const { 35 return P(x + X.x, y + X.y); 36 } 37 inline P operator - (const P &X) const { 38 return P(x - X.x, y - X.y); 39 } 40 inline P operator * (const lf &X) const { 41 return P(x * X, y * X); 42 } 43 inline lf operator * (const P &X) const { 44 return x * X.y - y * X.x; 45 } 46 inline lf operator / (const P &X) const { 47 return x * X.x + y * X.y; 48 } 49 inline void read() { 50 scanf("%lf%lf", &x, &y); 51 } 52 }p[N], s[N], t[5]; 53 54 int n, top; 55 lf ans = 1e60; 56 57 inline lf sqr(lf x) { 58 return x * x; 59 } 60 61 inline lf dis(P a, P b) { 62 return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y)); 63 } 64 65 inline bool cmp_p(P a, P b) { 66 lf tmp = (a - p[1]) * (b - p[1]); 67 return fabs(tmp) < eps ? dis(a, p[1]) - dis(b, p[1]) < eps : tmp > -eps; 68 } 69 70 void graham() { 71 int i; 72 for (i = 2; i <= n; ++i) 73 if (p[i] < p[1]) swap(p[1], p[i]); 74 sort(p + 2, p + n + 1, cmp_p); 75 for (i = 2, s[top = 1] = p[1]; i <= n; ++i) { 76 while (top > 1 && (s[top] - s[top - 1]) * (p[i] - s[top]) < eps) --top; 77 s[++top] = p[i]; 78 } 79 s[0] = s[top]; 80 } 81 82 inline bool check_p(int i, int p) { 83 return (s[i + 1] - s[i]) * (s[p + 1] - s[i]) - (s[i + 1] - s[i]) * (s[p] - s[i]) > -eps; 84 } 85 86 inline bool check_r(int i, int r) { 87 return (s[i + 1] - s[i]) / (s[r + 1] - s[i]) - (s[i + 1] - s[i]) / (s[r] - s[i]) > -eps; 88 } 89 90 inline bool check_l(int i, int l) { 91 return (s[i + 1] - s[i]) / (s[l + 1] - s[i]) - (s[i + 1] - s[i]) / (s[l] - s[i]) < eps; 92 } 93 94 void work() { 95 int l, r, p, i; 96 lf L, R, H, D, tmp; 97 for (i = 0, l = r = p = 1; i < top; ++i) { 98 D = dis(s[i], s[i + 1]); 99 while (check_p(i, p)) (p += 1) %= top;100 while (check_r(i, r)) (r += 1) %= top;101 if (!i) l = r;102 while (check_l(i, l)) (l += 1) %= top;103 L = (s[i + 1] - s[i]) / (s[l] - s[i]) / D;104 R = (s[i + 1] - s[i]) / (s[r] - s[i]) / D;105 H = (s[i + 1] - s[i]) * (s[p] - s[i]) / D;106 if (H < 0) H = -H;107 tmp = (R - L) * H;108 if (tmp < ans) {109 ans = tmp;110 t[0] = s[i] + (s[i + 1] - s[i]) * (R / D);111 t[1] = t[0] + (s[r] - t[0]) * (H / dis(t[0], s[r]));112 t[2] = t[1] - (t[0] - s[i]) * ((R - L) / dis(s[i], t[0]));113 t[3] = t[2] - (t[1] - t[0]);114 }115 }116 }117 118 int main() {119 int i, st;120 scanf("%d", &n);121 for (i = 1; i <= n; ++i)122 p[i].read();123 graham();124 work();125 for (i = 1, st = 0; i <= 3; ++i)126 if (t[i] < t[st]) st = i;127 for (i = 0, printf("%.5lf\n", ans); i <= 3; ++i)128 printf("%.5lf %.5lf\n", t[(i + st) % 4].x, t[(i + st) % 4].y);129 return 0;130 }
BZOJ1185 [HNOI2007]最小矩形覆盖
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。