题意:无线网络基站在理想状况下有效信号覆盖范围是个圆形。而无线基站的功耗与圆的半径的平方成正比。
现给出平面上若干网络用户的位置,请你选择一个合适的位置建设无线基站....
就在你拿起键盘准备开始敲代码的时候,你的好朋友发明家 SHTSC 突然出现了。SHTSC 刚刚完成了他的新发明——无线信号增幅仪。增幅仪能够在不增加无线基站功耗的前提下,使得有效信号的覆盖范围在某一特定方向上伸长若干倍。即:使用了增幅仪的无线基站覆盖范围是个椭圆,其功耗正比于半短轴长的平方。现给出平面上若干网络用户的位置,请你选择一个合适的位置建设无线基站,并在增幅仪的帮助下使所有的用户都能接收到信号,且无线基站的功耗最小。
注意:由于 SHTSC 增幅仪的工作原理依赖地磁场,增幅的方向是恒定的。
相当于是一个被拉长的圆,那么先将坐标轴旋转之后再把每个点横坐标缩成增幅倍数分之一即可
(这里的代码可能有小bug,建议看前一篇最小圆覆盖的)
#include<bits/stdc++.h>
#define db double
using namespace std;
const int N=100010;
const db eps=1e-7;
const db pi=acos(-1);
struct gg{
db x,y;
}node[N],O;
db r,apha,p;
int dcmp(db x)
{return x<-eps?-1:x>eps;}
db pf(db x)
{return x*x;}
db dis(gg x,gg y)
{return sqrt(pf(x.x-y.x)+pf(x.y-y.y));}
void get(db a1,db b1,db c1,db a2,db b2,db c2)
{
db k;k=a2/a1;
O.y=(c2-k*c1)/(b2-k*b1);
O.x=(c1-b1*O.y)/a1;
}
int idx[N],n;
int main()
{
srand(23336666);
scanf("%d",&n);
for(int i=1;i<=n;i++)idx[i]=i;
random_shuffle(idx+1,idx+n+1);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&node[idx[i]].x,&node[idx[i]].y);
scanf("%lf%lf",&apha,&p),apha=apha/180*pi;
db a,b,x,y;
for(int i=1;i<=n;i++)
{
x=node[i].x,y=node[i].y;
b=x/cos(apha);
a=(y-b*sin(apha))*sin(apha);
node[i].x=(a+b)/p;
node[i].y=x*a/(b*sin(apha));
}
O.x=(node[1].x+node[2].x)/2,O.y=(node[1].y+node[2].y)/2;
r=dis(O,node[1]);
for(int i=3;i<=n;i++)
{
if(dcmp(dis(O,node[i])-r)>0)
{
O=node[i],r=0;
for(int j=1;j<i;j++)
{
if(dcmp(dis(O,node[j])-r)>0)
{
O.x=(node[i].x+node[j].x)/2;
O.y=(node[i].y+node[j].y)/2;
r=dis(O,node[i]);
for(int k=1;k<j;k++)
{
if(dcmp(dis(O,node[k])-r)>0)
{
get(
2*(node[j].x-node[i].x),2*(node[j].y-node[i].y),pf(node[j].x)+pf(node[j].y)-pf(node[i].x)-pf(node[i].y),
2*(node[k].x-node[i].x),2*(node[k].y-node[i].y),pf(node[k].x)+pf(node[k].y)-pf(node[i].x)-pf(node[i].y)
);
r=dis(O,node[i]);
}
}
}
}
}
}
printf("%.3lf\n",r);
}