bzoj3564[SHOI2014]信号增幅仪

3564: [SHOI2014]信号增幅仪

Time Limit: 40 Sec  Memory Limit: 256 MB
Submit: 738  Solved: 290
[Submit][Status][Discuss]

Description

无线网络基站在理想状况下有效信号覆盖范围是个圆形。而无线基站的功耗与圆的半径的平方成正比。现给出平面
上若干网络用户的位置,请你选择一个合适的位置建设无线基站....就在你拿起键盘准备开始敲代码的时候,你的好
朋友发明家 SHTSC 突然出现了。SHTSC 刚刚完成了他的新发明——无线信号增幅仪。增幅仪能够在不增加无线基
站功耗的前提下,使得有效信号的覆盖范围在某一特定方向上伸长若干倍。即:使用了增幅仪的无线基站覆盖范围是
个椭圆,其功耗正比于半短轴长的平方。现给出平面上若干网络用户的位置,请你选择一个合适的位置建设无线基站
,并在增幅仪的帮助下使所有的用户都能接收到信号,且无线基站的功耗最小。注意:由于SHTSC 增幅仪的工作原理
依赖地磁场,增幅的方向是恒定的。

Input

第一行一个整数:n。平面内的用户个数。之后的 n 行每行两个整数 x, y,表示一个用户的位置。第 n+2 行一个整
数:a。表示增幅仪的增幅方向,单位是度。表示增幅仪的方向是从 x 正方向逆时针转 a 度。第 n+3 行一个整数:p
。表示增幅仪的放大倍数。

Output

输出一行一个实数,为能够覆盖所有用户的最小椭圆的半短轴长,四舍五入到三位小数。

Sample Input

样例一:
2
1 0
-1 0
0
2

Sample Output

样例一:
0.500

HINT

对于 100%的数据,n≤50000,0≤a<180,1≤p≤100,|x|,|y|≤2×10^8。

Source

By 佚名提供

坐标系直到x轴与椭圆长轴平行
点的坐标变换用旋转公式就可以了
因为是椭圆,所以所有点横坐标 除上p
然后最小圆覆盖

 1 #include<bits/stdc++.h>
 2 #define N 50005
 3 using namespace std;
 4 int n,deg,p;double r;
 5 const double pi=acos(-1);
 6 struct P{
 7     double x,y;
 8     P operator - (const P &b)const{return (P){x-b.x,y-b.y};}
 9 }a[N],c;
10 
11 P rotate(P t,int tmp){
12     double rt=1.0*tmp/180*pi;P ret;
13     ret.x=t.x*cos(rt)-t.y*sin(rt);
14     ret.y=t.x*sin(rt)+t.y*cos(rt);
15     return ret;
16 }
17 double len(P a){return sqrt(a.x*a.x+a.y*a.y);}
18 P getcentre(P A,P B,P C){
19     double a1=B.x-A.x,b1=B.y-A.y,c1=(a1*a1+b1*b1)/2;
20     double a2=C.x-A.x,b2=C.y-A.y,c2=(a2*a2+b2*b2)/2;
21     double d=a1*b2-b1*a2;P ret;
22     ret.x=A.x+(c1*b2-c2*b1)/d;
23     ret.y=A.y+(c2*a1-c1*a2)/d;
24     return ret;
25 }
26 void getcircle(){
27     random_shuffle(a+1,a+1+n);
28     c=a[1];r=0;
29     for(int i=1;i<=n;i++){
30         if(len(a[i]-c)<=r)continue;
31         c=a[i];r=0;
32         for(int j=1;j<i;j++){
33             if(len(a[j]-c)<=r)continue;
34             c.x=(a[i].x+a[j].x)/2;
35             c.y=(a[i].y+a[j].y)/2;
36             r=len(a[j]-c);
37             for(int k=1;k<j;k++){
38                 if(len(a[k]-c)<=r)continue;
39                 c=getcentre(a[i],a[j],a[k]);
40                 r=len(a[i]-c);
41             }
42         }
43     }
44 }
45 int main(){
46     scanf("%d",&n);
47     for(int i=1;i<=n;i++)
48     scanf("%lf%lf",&a[i].x,&a[i].y);
49     scanf("%d%d",&deg,&p);
50     for(int i=1;i<=n;i++)
51     a[i]=rotate(a[i],-deg),a[i].x/=p;
52     getcircle();printf("%.3lf
",r);
53     return 0;
54 }
原文地址:https://www.cnblogs.com/wsy01/p/8324712.html