BZOJ1185 [HNOI2007]最小矩形覆盖
2015-01-01 21:25
363 查看
一道计算几何裸题。。。调了蒟蒻两个小时。。。
问题出在求dis的时候忘了sqrt了,好了你现在可以退役滚蛋了,简直侮辱我们搞OI的人的智商
首先求个凸包出来,矩形的一边一定和凸包上一边重合。
然后枚举凸包上的边,用三个点同时旋转卡壳,卡出最小的矩形。
这题目写的我。。。醉了
View Code
问题出在求dis的时候忘了sqrt了,好了你现在可以退役滚蛋了,简直侮辱我们搞OI的人的智商
首先求个凸包出来,矩形的一边一定和凸包上一边重合。
然后枚举凸包上的边,用三个点同时旋转卡壳,卡出最小的矩形。
这题目写的我。。。醉了
/************************************************************** Problem: 1185 User: rausen Language: C++ Result: Accepted Time:180 ms Memory:2372 kb ****************************************************************/ #include <cstdio> #include <cmath> #include <algorithm> #define P Point using namespace std; typedef double lf; const int N = 50005; const lf eps = 1e-8; struct Point { lf x, y; P() {} P(lf _x, lf _y) : x(_x), y(_y) {} inline bool operator < (const P &X) const { return fabs(y - X.y) < eps ? x < X.x : y < X.y; } inline bool operator == (const P &X) const { return fabs(x - X.x) < eps && fabs(y - X.y) < eps; } inline bool operator != (const P &X) const { return !(*this == X); } inline P operator + (const P &X) const { return P(x + X.x, y + X.y); } inline P operator - (const P &X) const { return P(x - X.x, y - X.y); } inline P operator * (const lf &X) const { return P(x * X, y * X); } inline lf operator * (const P &X) const { return x * X.y - y * X.x; } inline lf operator / (const P &X) const { return x * X.x + y * X.y; } inline void read() { scanf("%lf%lf", &x, &y); } }p , s , t[5]; int n, top; lf ans = 1e60; inline lf sqr(lf x) { return x * x; } inline lf dis(P a, P b) { return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y)); } inline bool cmp_p(P a, P b) { lf tmp = (a - p[1]) * (b - p[1]); return fabs(tmp) < eps ? dis(a, p[1]) - dis(b, p[1]) < eps : tmp > -eps; } void graham() { int i; for (i = 2; i <= n; ++i) if (p[i] < p[1]) swap(p[1], p[i]); sort(p + 2, p + n + 1, cmp_p); for (i = 2, s[top = 1] = p[1]; i <= n; ++i) { while (top > 1 && (s[top] - s[top - 1]) * (p[i] - s[top]) < eps) --top; s[++top] = p[i]; } s[0] = s[top]; } inline bool check_p(int i, int p) { return (s[i + 1] - s[i]) * (s[p + 1] - s[i]) - (s[i + 1] - s[i]) * (s[p] - s[i]) > -eps; } inline bool check_r(int i, int r) { return (s[i + 1] - s[i]) / (s[r + 1] - s[i]) - (s[i + 1] - s[i]) / (s[r] - s[i]) > -eps; } inline bool check_l(int i, int l) { return (s[i + 1] - s[i]) / (s[l + 1] - s[i]) - (s[i + 1] - s[i]) / (s[l] - s[i]) < eps; } void work() { int l, r, p, i; lf L, R, H, D, tmp; for (i = 0, l = r = p = 1; i < top; ++i) { D = dis(s[i], s[i + 1]); while (check_p(i, p)) (p += 1) %= top; while (check_r(i, r)) (r += 1) %= top; if (!i) l = r; while (check_l(i, l)) (l += 1) %= top; L = (s[i + 1] - s[i]) / (s[l] - s[i]) / D; R = (s[i + 1] - s[i]) / (s[r] - s[i]) / D; H = (s[i + 1] - s[i]) * (s[p] - s[i]) / D; if (H < 0) H = -H; tmp = (R - L) * H; if (tmp < ans) { ans = tmp; t[0] = s[i] + (s[i + 1] - s[i]) * (R / D); t[1] = t[0] + (s[r] - t[0]) * (H / dis(t[0], s[r])); t[2] = t[1] - (t[0] - s[i]) * ((R - L) / dis(s[i], t[0])); t[3] = t[2] - (t[1] - t[0]); } } } int main() { int i, st; scanf("%d", &n); for (i = 1; i <= n; ++i) p[i].read(); graham(); work(); for (i = 1, st = 0; i <= 3; ++i) if (t[i] < t[st]) st = i; for (i = 0, printf("%.5lf\n", ans); i <= 3; ++i) printf("%.5lf %.5lf\n", t[(i + st) % 4].x, t[(i + st) % 4].y); return 0; }
View Code
相关文章推荐
- bzoj1185 [HNOI2007]最小矩形覆盖
- BZOJ1185 [HNOI2007]最小矩形覆盖 【旋转卡壳】
- BZOJ:1185: [HNOI2007]最小矩形覆盖
- BZOJ 1185 [HNOI2007]最小矩形覆盖 旋转卡壳
- bzoj 1185 [HNOI2007]最小矩形覆盖 凸包+旋转卡壳
- bzoj 1185: [HNOI2007]最小矩形覆盖 (旋转卡壳)
- BZOJ1185 [HNOI2007]最小矩形覆盖
- BZOJ 1185 HNOI 2007 最小矩形覆盖 旋转卡壳
- BZOJ1185 : [HNOI2007]最小矩形覆盖
- [BZOJ1185][HNOI2007]最小矩形覆盖(凸包+旋转卡壳)
- [BZOJ1185][HNOI2007]最小矩形覆盖(计算几何-旋转卡壳)
- BZOJ 1185: [HNOI2007]最小矩形覆盖
- 【HNOI2007】bzoj1185 最小矩形覆盖
- BZOJ 1185: [HNOI2007]最小矩形覆盖 [旋转卡壳]
- BZOJ 1185 [HNOI2007]最小矩形覆盖 ——计算几何
- Bzoj1185 [HNOI2007]最小矩形覆盖
- [省选前题目整理][BZOJ 1185][HNOI 2007]最小矩形覆盖(旋转卡壳)
- bzoj1185 [HNOI2007]最小矩形覆盖
- 【旋转卡壳+凸包】BZOJ1185:[HNOI2007]最小矩形覆盖