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
原文地址:https://www.cnblogs.com/rausen/p/4352006.html