题意 就是找到一个 位置 使得路由器可以覆盖所有英雄 可以不覆盖主人自己, 找到距离 主人房子最近的位置,距离为多少
没想到 其实是道水题啊!! 分三个情况讨论
第一个情况 如果 把主人的位置放上路由器 可以 覆盖到所有英雄,则答案出来了 0( 一个 半径为 d 的圆,边界上没有点);
第二个情况 考虑 圆上只有一个点,这个圆只受到该点的约束( 则圆心在 连线上);
第三个情况 两个点 或者更多点确定那个圆, 则当两个点或者更多的点都距离为d 时确定那个圆心;因为如果那个点的距离没有到d 证明我还可以更靠近一点房子
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<stdio.h> 5 #include<cmath> 6 #include<vector> 7 #include<functional> 8 #define eps 1e-9 9 using namespace std; 10 const double PI = acos( -1.0 ); 11 inline int dcmp( double x ){if( abs(x) < eps )return 0;else return x<0?-1:1;} 12 struct point{ 13 double x,y; 14 point( double x = 0,double y = 0 ):x(x),y(y){} 15 }node[112345]; 16 typedef point Vector; 17 typedef vector<point>ploygon; 18 inline point operator+( point a,point b ){ return point(a.x+b.x,a.y+b.y); } 19 inline point operator-( point a,point b ){ return point(a.x-b.x,a.y-b.y); } 20 inline point operator*( point a,double p){ return point(a.x*p,a.y*p); } 21 inline point operator/( point a,double p){ return point(a.x/p,a.y/p); } 22 inline bool operator< ( const point &a,const point &b ){return a.x<b.x||(a.x==b.x&&a.y<b.y);} 23 inline bool operator==( const point &a,const point &b ){return (dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0);} 24 inline bool operator!=( const point &a,const point &b ){return a==b?false:true;} 25 26 inline double Dot( point a,point b ){ return a.x*b.x + a.y*b.y; } 27 inline double Cross( point a,point b ){ return a.x*b.y - a.y*b.x; } 28 inline double Length( point a ){ return sqrt(Dot(a,a)); } 29 inline double Angle( point a,point b ){ 30 double right = Dot(a,b)/Length(a)/Length(b); 31 return acos(right); 32 } 33 inline point Rotate( point a,double rad ){ 34 return point( a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad+a.y*cos(rad)) ); 35 } 36 point A[1123]; int N; double dis; 37 bool work( point temp ) 38 { 39 for( int i = 1; i <= N; i++ ) 40 if( Length( A[i]-temp ) > dis && abs(Length( A[i] - temp ) - dis) > eps ){ 41 return false;} 42 return true; 43 } 44 int main( ) 45 { 46 //freopen( "ou.txt","r",stdin); 47 //freopen( "in.txt","w",stdout); 48 while( scanf("%lf%lf%lf",&A[0].x,&A[0].y,&dis) != EOF ) 49 { 50 scanf("%d",&N); 51 for( int i = 1; i <= N; i++ ) 52 scanf("%lf%lf",&A[i].x,&A[i].y); 53 double Max = (1<<30); bool fell = false; 54 for( int i = 1; i <= N; i++ ) 55 if( Length( A[0]-A[i] ) > dis )fell = true; 56 if( !fell ){ puts("0.00");continue;} 57 double Min = (1<<30); 58 for( int i = 1; i <= N; i++ ){ 59 point temp = A[i] + (A[0] - A[i])*(dis/Length(A[0]-A[i])); 60 if( Length( temp-A[0] ) < Min ) if( work( temp ) ) 61 Min = min( Min,Length(temp-A[0]) ); 62 } 63 for( int i = 1; i <= N; i++ ) 64 for( int j = i+1; j <= N; j++ ) 65 { 66 point temp = (A[i]+A[j])/2.0; double D = Length(A[i]-A[j])*0.5; 67 Vector now1 = Rotate( (A[i]-A[j]),PI/2.0 )*sqrt(dis*dis-D*D)/(D*2.0); 68 Vector now2 = Rotate( (A[i]-A[j]),-PI/2.0 )*sqrt(dis*dis-D*D)/(D*2.0); 69 point temp1 = temp + now1; 70 point temp2 = temp + now2; 71 if( Length( temp1-A[0] ) < Min ) if( work( temp1 ) ) 72 Min = min( Min,Length(temp1-A[0]) ); 73 if( Length( temp2-A[0] ) < Min ) if( work( temp2 ) ) 74 Min = min( Min,Length(temp2-A[0]) ); 75 } 76 if( Min == (1<<30) )puts("X"); 77 else printf("%.2lf ",Min); 78 } 79 return 0; 80 } 81 /* 82 83 2600 10712 5075 84 1 85 26869 21003 86 87 */