2823: [AHOI2012]信号塔
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1190 Solved: 545
[Submit][Status][Discuss]
Description
在野外训练中,为了确保每位参加集训的成员安全,实时的掌握和收集周边环境和队员信息非常重要,集训队采用
的方式是在训练所在地散布N个小型传感器来收集并传递信息,这些传感器只与设在集训地中的信号塔进行通信,
信号塔接收信号的覆盖范围是圆形,可以接收到所有分布在该集训区域内所有N个小型传感器(包括在该圆形的边
上)发出的信号。信号塔的功率与信号塔接收范围半径的大小成正比,因为是野外训练,只能使用事先储备好的蓄
电设备,因此在可以收集所有传感器信息的基础上,还应使得信号塔的功率最小。小龙帮助教官确定了一种信号塔
设置的方案,既可以收集到所有N个传感器的信号,又可以保证这个信号塔的功率是最小的。同学们,你们知道,
这个信号塔的信号收集半径有多大,它应该设置在何处吗?
Input
共N+1行,第一行为正整数N(1≤N≤1000000),表示队员个数。接下来N行,每行两个实数用空格分开,分别是第
i个队员的坐标X
Output
一行,共三个实数(中间用空格隔开),分别是信号塔的坐标,和信号塔 覆盖的半径。 (注:队员是否在边界上
的判断应符合他到圆心的距离与信号塔接收半径之差的绝对值小于10^-6
Sample Input
5
1.200 1.200
2.400 2.400
3.800 4.500
2.500 3.100
3.900 1.300
1.200 1.200
2.400 2.400
3.800 4.500
2.500 3.100
3.900 1.300
Sample Output
2.50 2.85 2.10
HINT
1≤N≤500000
最小圆覆盖裸题
1 #include<bits/stdc++.h> 2 #define N 500010 3 using namespace std; 4 int n;double r; 5 const double eps=1e-8; 6 struct P{ 7 double x,y; 8 P operator - (const P &b)const{return (P){x-b.x,y-b.y};} 9 double len(){return sqrt(x*x+y*y);} 10 }a[N],c; 11 12 P getcentre(P A,P B,P C){ 13 P ret; 14 double a1=B.x-A.x,b1=B.y-A.y,c1=(a1*a1+b1*b1)/2; 15 double a2=C.x-A.x,b2=C.y-A.y,c2=(a2*a2+b2*b2)/2; 16 double d=a1*b2-a2*b1; 17 ret.x=A.x+(c1*b2-c2*b1)/d; 18 ret.y=A.y+(a1*c2-a2*c1)/d; 19 return ret; 20 } 21 22 void getcircle(){ 23 random_shuffle(a+1,a+1+n); 24 c=a[1];r=0; 25 for(int i=1;i<=n;i++){ 26 if((a[i]-c).len()>r+eps){ 27 c=a[i];r=0; 28 for(int j=1;j<i;j++){ 29 if((a[j]-c).len()>r+eps){ 30 c.x=(a[i].x+a[j].x)/2; 31 c.y=(a[i].y+a[j].y)/2; 32 r=(a[j]-c).len(); 33 for(int k=1;k<j;k++){ 34 if((a[k]-c).len()>r+eps){ 35 c=getcentre(a[i],a[j],a[k]); 36 r=(a[i]-c).len(); 37 } 38 } 39 } 40 } 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 getcircle(); 50 printf("%.2lf %.2lf %.2lf\n",c.x,c.y,r); 51 return 0; 52 }