hdu3264Open-air shopping malls(二分)

链接

枚举伞的圆心,最多只有20个,因为必须与某个现有的圆心重合。

然后再二分半径就可以了。

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 25
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 struct point
18 {
19     double x,y;
20     double r,s;
21     point(double x=0,double y=0):x(x),y(y) {}
22 } p[N];
23 int n;
24 typedef point pointt;
25 pointt operator -(point a,point b)
26 {
27     return point(a.x-b.x,a.y-b.y);
28 }
29 int dcmp(double x)
30 {
31     if(fabs(x)<eps) return 0;
32     return x<0?-1:1;
33 }
34 double circle_area(point a,point b)
35 {
36     double s,d,t,t1;
37     d=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
38     if(d>=a.r+b.r) s=0;
39     else if(d<=fabs(a.r-b.r)) s=min(acos(-1.0)*a.r*a.r,acos(-1.0)*b.r*b.r);
40     else
41     {
42         t=(a.r*a.r+d*d-b.r*b.r)/2.0/d;
43         t1=sqrt(a.r*a.r-t*t);
44         s=-d*t1+a.r*a.r*acos(t/a.r)+b.r*b.r*acos((d-t)/b.r);
45     }
46     return s;
47 }
48 int cal(double mid,point pp)
49 {
50     int i;
51     double sum;
52     pp.r = mid;
53     for(i = 1 ; i <= n ; i++)
54     {
55         sum = circle_area(pp,p[i]);
56         if(dcmp(sum-p[i].s/2)<0) return 0;
57     }
58     //cout<<mid<<" "<<pp.x<<" "<<pp.y<<" "<<pp.r<<endl;
59     return 1;
60 }
61 double solve(point pp)
62 {
63     double rig = 20001,lef = 0,mid;
64     while(rig-lef>eps)
65     {
66         mid = (rig+lef)/2;
67         if(cal(mid,pp))
68         rig = mid;
69         else lef = mid;
70     }
71     return rig;
72 }
73 int main()
74 {
75     int t,i;
76     cin>>t;
77     while(t--)
78     {
79         scanf("%d",&n);
80         for(i = 1; i <= n ; i++)
81         {
82             scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].r);
83             p[i].s = pi*p[i].r*p[i].r;
84         }
85         double ans = INF;
86         for(i = 1; i <= n ; i++)
87         {
88             ans = min(ans,solve(p[i]));
89         }
90         printf("%.4f\n",ans);
91     }
92     return 0;
93 }
View Code

 

posted @ 2014-08-05 08:53  _雨  阅读(143)  评论(0编辑  收藏  举报