zoukankan      html  css  js  c++  java
  • BZOJ2280 [Poi2011]Plot

    恩。。这题真是sxbk

    我们先二分答案,然后判断答案是否满足要求

    判断方法是二分当前段的长度一直做到底,当然我们可以用倍增这样快一点,直接随机增量就可以了

    然后就是卡常。。。。。

    然后就是卡精度QAQQQQQQQ没了

      1 /**************************************************************
      2     Problem: 2280
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:90955 ms
      7     Memory:7068 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cmath>
     12 #include <algorithm>
     13  
     14 using namespace std;
     15 typedef double lf;
     16 typedef long double LF;
     17 const int N = 1e5 + 5;
     18 const LF eps = 1e-7;
     19 const LF EPS = 1e-13;
     20 const LF inf = 1e8;
     21  
     22 inline int read();
     23 inline void print(const lf&);
     24  
     25 template <class T> inline T sqr(const T &x) {
     26     return x * x;
     27 }
     28  
     29 struct point {
     30     lf x, y;
     31     point() {}
     32     point(lf _x, lf _y) : x(_x), y(_y) {}
     33      
     34     friend inline point operator + (const point &p, const point &q) {
     35         return point(p.x + q.x, p.y + q.y);
     36     }
     37     friend inline point operator - (const point &p, const point &q) {
     38         return point(p.x - q.x, p.y - q.y);
     39     }
     40     friend inline LF operator * (const point &p, const point &q) {
     41         return p.x * q.y - p.y * q.x;
     42     }
     43     friend inline point operator / (const point &p, const LF &d) {
     44         return point(p.x / d, p.y / d);
     45     }
     46      
     47     inline void read_in() {
     48         x = read(), y = read();
     49     }
     50     inline void print_out() {
     51         print(x), putchar(' '), print(y), putchar('
    ');
     52     }
     53     friend inline LF dis2(const point &p) {
     54         return sqr((LF) p.x) + sqr((LF) p.y);
     55     }
     56     friend inline lf dis(const point &p) {
     57         return sqrt(dis2(p));
     58     }
     59     friend inline point work(const point &a, const point &b, const point &c) {
     60         point p = b - a, q = c - a, res;
     61         LF d = p * q * 2;
     62         if (fabs(d) < EPS) {
     63             lf ab = dis2(b - a), bc = dis2(c - b), ac = dis2(c - a);
     64             if (ab - bc >= EPS && ab - ac >= EPS) return (a + b) / 2;
     65             if (bc - ab >= EPS && bc - ac >= EPS) return (b + c) / 2;
     66             return (a + c) / 2;
     67         }
     68         return point(dis2(p) * q.y - dis2(q) * p.y, dis2(q) * p.x - dis2(p) * q.x) / d + a;
     69 }
     70 } p[N], q[N], c[N], ans[N];
     71  
     72 int n, m, cnt;
     73 LF rad, now_ans;
     74  
     75 inline void min_cover(const int &L, const int &st, const int &R) {
     76     static int i, j, k;
     77     for (i = st; i <= R; ++i) if (dis2(q[i] - c[cnt]) > rad) {
     78         c[cnt] = q[i], rad = 0.0;
     79         for (j = L; j < i; ++j) if (dis2(q[j] - c[cnt]) > rad) {
     80             c[cnt] = (q[i] + q[j]) / 2.0, rad = dis2(q[i] - c[cnt]);
     81             for (k = L; k < j; ++k) if (dis2(q[k] - c[cnt]) > rad)
     82                 c[cnt] = work(q[i], q[j], q[k]), rad = dis2(q[i] - c[cnt]);
     83         }
     84     }
     85 }
     86  
     87 inline bool check(const int &l, const int &st, const int &r) {
     88     static int i;
     89     for (i = st; i <= r; ++i) q[i] = p[i];
     90     random_shuffle(q + st, q + r + 1);
     91     if (st == l) c[cnt] = q[l], rad = 0.0;
     92     min_cover(l, st, r);
     93     return rad < now_ans + eps;
     94 }
     95  
     96 inline bool check_ans() {
     97     static int l, len, del;
     98     cnt = l = 0, del = 1;
     99     while (l + del <= n) {
    100         ++cnt;
    101         if (cnt > m) return 0;
    102         l += del, del = 0;
    103         for (len = 1; l + len - 1 <= n && check(l, l + (len >> 1), l + len - 1); len <<= 1);
    104         del += (len >>= 1);
    105         for (; len; len >>= 1)
    106             if (l + del + len - 1 <= n && check(l, l, l + del + len - 1)) del += len;
    107     }
    108     return 1;
    109 }
    110  
    111 inline void get_ans() {
    112     static int l, len, del;
    113     cnt = l = 0, del = 1;
    114     while (l + del <= n) {
    115         ++cnt;
    116         l += del, del = 0;
    117         for (len = 1; l + len - 1 <= n && check(l, l + (len >> 1), l + len - 1); len <<= 1);
    118         del += (len >>= 1);
    119         for (; len; len >>= 1)
    120             if (l + del + len - 1 <= n && check(l, l, l + del + len - 1)) del += len;
    121         check(l, l, l + del - 1), ans[cnt] = c[cnt];
    122     }
    123 }
    124  
    125 int main() {
    126     int i;
    127     LF ansl, ansr, mid;
    128     n = read(), m = read();
    129     for (i = 1; i <= n; ++i) p[i].read_in();
    130     ansl = 0, ansr = inf;
    131     while (ansr - ansl > eps) {
    132         mid = (ansl + ansr) / 2.0;
    133         now_ans = sqr(mid);
    134         if (check_ans()) ansr = mid;
    135         else ansl = mid;
    136     }
    137     now_ans = sqr(ansr);
    138     get_ans();
    139     print(ansr);
    140     printf("
    %d
    ", cnt);
    141     for (i = 1; i <= cnt; ++i) ans[i].print_out();
    142     return 0;
    143 }
    144  
    145 inline int read() {
    146     static int x, sgn;
    147     static char ch;
    148     x = 0, sgn = 1, ch = getchar();
    149     while (ch < '0' || '9' < ch) {
    150         if (ch == '-') sgn = -1;
    151         ch = getchar();
    152     }
    153     while ('0' <= ch && ch <= '9') {
    154         x = x * 10 + ch - '0';
    155         ch = getchar();
    156     }
    157     return sgn * x;
    158 }
    159  
    160 inline void print(const lf &x) {
    161     static int a, tot, pr[20];
    162     static lf t;
    163     if (x < 0) putchar('-'), t = -x;
    164     else t = x;
    165     a = (int) t, t -= a, tot = 0;
    166     while (a)
    167         pr[++tot] = a % 10, a /= 10;
    168     if (!tot) putchar('0');
    169     while (tot) putchar(pr[tot--] + '0');
    170     putchar('.');
    171     for (tot = 1; tot <= 8; ++tot)
    172         t *= 10, putchar((int) t % 10 + '0');
    173 }
    View Code

     (p.s. 数据在这里,求不要像我一样虐萌萌哒main和bz评测姬)

    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    记录MySQL中优化sql语句查询常用的30种方法
    记录分布式和集群的区别
    TCP的三次握手与四次挥手理解及面试题(很全面)
    记录Linux常用命令大全
    DNS解析流程
    dup和dup2用法小结
    c++多态的实现
    linux下常见的字符串处理
    ncurses库的一些函数
    用两个栈实现一个队列
  • 原文地址:https://www.cnblogs.com/rausen/p/4352006.html
Copyright © 2011-2022 走看看