BZOJ2280 [Poi2011]Plot

恩。。这题真是sxbk

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

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

然后就是卡常。。。。。

然后就是卡精度QAQQQQQQQ没了

 /**************************************************************
Problem: 2280
User: rausen
Language: C++
Result: Accepted
Time:90955 ms
Memory:7068 kb
****************************************************************/ #include <cstdio>
#include <cmath>
#include <algorithm> using namespace std;
typedef double lf;
typedef long double LF;
const int N = 1e5 + ;
const LF eps = 1e-;
const LF EPS = 1e-;
const LF inf = 1e8; inline int read();
inline void print(const lf&); template <class T> inline T sqr(const T &x) {
return x * x;
} struct point {
lf x, y;
point() {}
point(lf _x, lf _y) : x(_x), y(_y) {} friend inline point operator + (const point &p, const point &q) {
return point(p.x + q.x, p.y + q.y);
}
friend inline point operator - (const point &p, const point &q) {
return point(p.x - q.x, p.y - q.y);
}
friend inline LF operator * (const point &p, const point &q) {
return p.x * q.y - p.y * q.x;
}
friend inline point operator / (const point &p, const LF &d) {
return point(p.x / d, p.y / d);
} inline void read_in() {
x = read(), y = read();
}
inline void print_out() {
print(x), putchar(' '), print(y), putchar('\n');
}
friend inline LF dis2(const point &p) {
return sqr((LF) p.x) + sqr((LF) p.y);
}
friend inline lf dis(const point &p) {
return sqrt(dis2(p));
}
friend inline point work(const point &a, const point &b, const point &c) {
point p = b - a, q = c - a, res;
LF d = p * q * ;
if (fabs(d) < EPS) {
lf ab = dis2(b - a), bc = dis2(c - b), ac = dis2(c - a);
if (ab - bc >= EPS && ab - ac >= EPS) return (a + b) / ;
if (bc - ab >= EPS && bc - ac >= EPS) return (b + c) / ;
return (a + c) / ;
}
return point(dis2(p) * q.y - dis2(q) * p.y, dis2(q) * p.x - dis2(p) * q.x) / d + a;
}
} p[N], q[N], c[N], ans[N]; int n, m, cnt;
LF rad, now_ans; inline void min_cover(const int &L, const int &st, const int &R) {
static int i, j, k;
for (i = st; i <= R; ++i) if (dis2(q[i] - c[cnt]) > rad) {
c[cnt] = q[i], rad = 0.0;
for (j = L; j < i; ++j) if (dis2(q[j] - c[cnt]) > rad) {
c[cnt] = (q[i] + q[j]) / 2.0, rad = dis2(q[i] - c[cnt]);
for (k = L; k < j; ++k) if (dis2(q[k] - c[cnt]) > rad)
c[cnt] = work(q[i], q[j], q[k]), rad = dis2(q[i] - c[cnt]);
}
}
} inline bool check(const int &l, const int &st, const int &r) {
static int i;
for (i = st; i <= r; ++i) q[i] = p[i];
random_shuffle(q + st, q + r + );
if (st == l) c[cnt] = q[l], rad = 0.0;
min_cover(l, st, r);
return rad < now_ans + eps;
} inline bool check_ans() {
static int l, len, del;
cnt = l = , del = ;
while (l + del <= n) {
++cnt;
if (cnt > m) return ;
l += del, del = ;
for (len = ; l + len - <= n && check(l, l + (len >> ), l + len - ); len <<= );
del += (len >>= );
for (; len; len >>= )
if (l + del + len - <= n && check(l, l, l + del + len - )) del += len;
}
return ;
} inline void get_ans() {
static int l, len, del;
cnt = l = , del = ;
while (l + del <= n) {
++cnt;
l += del, del = ;
for (len = ; l + len - <= n && check(l, l + (len >> ), l + len - ); len <<= );
del += (len >>= );
for (; len; len >>= )
if (l + del + len - <= n && check(l, l, l + del + len - )) del += len;
check(l, l, l + del - ), ans[cnt] = c[cnt];
}
} int main() {
int i;
LF ansl, ansr, mid;
n = read(), m = read();
for (i = ; i <= n; ++i) p[i].read_in();
ansl = , ansr = inf;
while (ansr - ansl > eps) {
mid = (ansl + ansr) / 2.0;
now_ans = sqr(mid);
if (check_ans()) ansr = mid;
else ansl = mid;
}
now_ans = sqr(ansr);
get_ans();
print(ansr);
printf("\n%d\n", cnt);
for (i = ; i <= cnt; ++i) ans[i].print_out();
return ;
} inline int read() {
static int x, sgn;
static char ch;
x = , sgn = , ch = getchar();
while (ch < '' || '' < ch) {
if (ch == '-') sgn = -;
ch = getchar();
}
while ('' <= ch && ch <= '') {
x = x * + ch - '';
ch = getchar();
}
return sgn * x;
} inline void print(const lf &x) {
static int a, tot, pr[];
static lf t;
if (x < ) putchar('-'), t = -x;
else t = x;
a = (int) t, t -= a, tot = ;
while (a)
pr[++tot] = a % , a /= ;
if (!tot) putchar('');
while (tot) putchar(pr[tot--] + '');
putchar('.');
for (tot = ; tot <= ; ++tot)
t *= , putchar((int) t % + '');
}

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

上一篇:暑假练习赛 006 E Vanya and Label(数学)


下一篇:Nodejs 实现ESL内联FreeSWITCH设定说明