zoukankan      html  css  js  c++  java
  • 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
    ", ans); i <= 3; ++i)
    128         printf("%.5lf %.5lf
    ", t[(i + st) % 4].x, t[(i + st) % 4].y);
    129     return 0;
    130 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    (字符串)子串变位词
    反转链表 II
    翻转链表
    覆盖索引
    MySQL索引结构之Hash索引、full-text全文索引(面)
    MySQL索引结构之B+树索引(面)
    MYSQL 存储引擎(面)
    MySQL架构(面)
    如何在Linux Mint 20系统上安装Pip
    如何在CentOS 8系统服务器上安装Nginx
  • 原文地址:https://www.cnblogs.com/rausen/p/4197840.html
Copyright © 2011-2022 走看看