Description
无线网络基站在理想状况下有效信号覆盖范围是个圆形。而无线基站的功耗与圆的半径的平方成正比。现给出平面
上若干网络用户的位置,请你选择一个合适的位置建设无线基站….就在你拿起键盘准备开始敲代码的时候,你的好
朋友发明家 SHTSC 突然出现了。SHTSC 刚刚完成了他的新发明——无线信号增幅仪。增幅仪能够在不增加无线基
站功耗的前提下,使得有效信号的覆盖范围在某一特定方向上伸长若干倍。即:使用了增幅仪的无线基站覆盖范围是
个椭圆,其功耗正比于半短轴长的平方。现给出平面上若干网络用户的位置,请你选择一个合适的位置建设无线基站
,并在增幅仪的帮助下使所有的用户都能接收到信号,且无线基站的功耗最小。注意:由于SHTSC 增幅仪的工作原理
依赖地磁场,增幅的方向是恒定的。
对于 100%的数据,n≤50000,0≤a<180,1≤p≤100,|x|,|y|≤2×10^8。
Solution
火速切掉
有了垫底的知识就有想法了。长轴是斜的不好搞,那么转正即可。然后把所有x坐标缩小p倍,这样就是裸的最小圆覆盖了,随机增量法,注意精度
Code
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
const int N=50005;
const double Pi=3.1415926535897932;
const double EPS=0.000001;
struct pos{double x,y;}p[N],cir;
double r=0;
double sqr(double x) {return x*x;}
double get_dis(pos a,pos b) {return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}
pos get_mid(pos a,pos b) {return (pos){(a.x+b.x)*0.5,(a.y+b.y)*0.5};}
pos get_center(pos a,pos b,pos c) {
pos cen1=get_mid(a,b);
pos cen2=get_mid(a,c);
pos ret;
double k1,k2,b1,b2;
if (a.y==b.y) {
k2=-1.0/((c.y-a.y)/(c.x-a.x));
b2=cen2.y-k2*cen2.x;
ret=(pos){cen1.x,cen1.x*k2+b2};
} else if (a.y==c.y) {
k1=-1.0/((b.y-a.y)/(b.x-a.x));
b1=cen1.y-k1*cen1.x;
ret=(pos){cen2.x,cen2.x*k1+b1};
} else {
k1=-1.0/((b.y-a.y)/(b.x-a.x));
b1=cen1.y-k1*cen1.x;
k2=-1.0/((c.y-a.y)/(c.x-a.x));
b2=cen2.y-k2*cen2.x;
ret.x=(b1-b2)/(k2-k1); ret.y=k1*ret.x+b1;
}
return ret;
}
int main(void) {
int n,P; scanf("%d",&n);
double a;
rep(i,1,n) scanf("%lf%lf",&p[i].x,&p[i].y);
scanf("%lf%d",&a,&P);
a=-a*Pi/180.0;
if (a) rep(i,1,n) {
double x=cos(a)*p[i].x-sin(a)*p[i].y;
double y=sin(a)*p[i].x+cos(a)*p[i].y;
p[i]=(pos){x,y};
}
rep(i,1,n) p[i].x/=1.0*P;
std:: random_shuffle(p+1,p+n+1);
cir=p[1];
rep(i,2,n) {
double d=get_dis(p[i],cir);
if (d-r<=EPS) continue;
r=0; cir=p[i];
rep(j,1,i-1) {
if (get_dis(p[j],cir)-r<=EPS) continue;
r=get_dis(p[j],p[i])*0.5;
cir=get_mid(p[j],p[i]);
rep(k,1,j-1) {
if (get_dis(p[k],cir)-r<=EPS) continue;
cir=get_center(p[i],p[j],p[k]);
r=get_dis(cir,p[i]);
}
}
}
printf("%.3lf\n", r);
return 0;
}