Poj--3831(两圆相交,二分)
2014-12-03 01:32:33
思路:广州热身赛C题的原题,枚举大圆圆心,二分大圆半径。
1 /************************************************************************* 2 > File Name: p3831.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Wed 03 Dec 2014 12:50:01 AM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 const double PI = acos(-1.0); 27 const int RA = 1e9; 28 const double eps = 1e-8; 29 30 int T; 31 int N; 32 double X[30],Y[30],R[30]; 33 34 double Cal(double ax,double ay,double ar,double bx,double by,double br){ 35 double d = sqrt((ax - bx) * (ax - bx) + (ay - by) * (ay - by)); 36 if(d >= ar + br) 37 return 0.0; 38 double r = min(ar,br); 39 if(d <= fabs(ar - br)) 40 return PI * r * r; 41 double a1 = acos((ar * ar + d * d - br * br) / (2.0 * ar * d)); 42 double a2 = acos((br * br + d * d - ar * ar) / (2.0 * br * d)); 43 double ans = -d * ar * sin(a1); 44 ans += a1 * ar * ar + a2 * br * br; 45 return ans; 46 } 47 48 bool Check(int c,double r){ 49 for(int i = 1; i <= N; ++i){ 50 double s = PI * R[i] * R[i]; 51 double its = 2.0 * Cal(X[c],Y[c],r,X[i],Y[i],R[i]); 52 if(its < s) 53 return false; 54 } 55 return true; 56 } 57 58 int main(){ 59 double a,b,r; 60 scanf("%d",&T); 61 while(T--){ 62 scanf("%d",&N); 63 for(int i = 1; i <= N; ++i){ 64 scanf("%lf%lf%lf",&X[i],&Y[i],&R[i]); 65 } 66 double ans = INF; 67 for(int i = 1; i <= N; ++i){ 68 double l = 0,r = RA; 69 while(fabs(r - l) >= eps){ 70 double mid = getmid(l,r); 71 if(Check(i,mid)) 72 r = mid; 73 else 74 l = mid; 75 } 76 ans = min(ans,l); 77 } 78 printf("%.4f\n",ans); 79 } 80 return 0; 81 }