好难写啊!
这题如果保证数据随机,那么可以直接跑一个最小圆覆盖,先二分半径,再贪心覆盖。
但是出题人显然不会这么善良。 于是就可以倍增,\(1,2,4,8,16...\),这样尝试长度,找到最大可行二进制长度(即最高位)后,再逐位确定。 复杂度\(O(nlog^2(n))\) 但是写完之后又被卡了精度,改随机数种子才可以过。#includeusing namespace std;const int N=100010;typedef double ld;const ld EPS=1e-8;struct point{ ld x,y; ld distance(){ return sqrt(x*x+y*y); } point operator *(const ld &z) const{ return {z*x,z*y}; } point operator /(const ld &z) const{ return {x/z,y/z}; } ld operator ^(const point &_) const{ return x*_.x+y*_.y; } ld operator *(const point &_) const{ return x*_.y-y*_.x; } point operator +(const point &_) const{ return {x+_.x,y+_.y}; } ld sqr() const{ return x*x+y*y; } point operator -(const point &_) const{ return {x-_.x,y-_.y}; } point rotate(const ld &alpha) const{ ld tc=cos(alpha),ts=sin(alpha); return {x*tc-y*ts,x*ts+y*tc}; } point normal() const{ return {-y,x}; }}a[N],c[N];struct line{ point x,y; point generate(const ld &c) const{ return x+y*c; } point cross(const line &u) const{ ld s1=y*u.y; ld s2=u.y*(x-u.x); //cerr< <<" "< <<" "< <<" "< < mid*mid) break; for (int j=(i>>=1); j; j>>=1) if (x+i+j-1<=n&&check(x,x+i+j-1)<=mid*mid) i+=j; if (rec){ re=1; check(x,x+i-1); re=0; } return x+i;}bool maybe(const ld &mid){ //cerr<<"maybe:"< <