HDU3264 Open-air shopping malls【几何】

来源:互联网 发布:淘宝跳蚤街与闲鱼 编辑:程序博客网 时间:2024/05/17 20:52

题意:有很多圆,选其中一个圆的圆心作为新圆的圆心,新圆要求能覆盖每个圆面积的一半,求最小半径


思路:枚举每个圆,二分半径。这个要用到两个圆相交的面积,存下模板。


#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<stdlib.h>#include<math.h>#include<vector>#include<list>#include<map>#include<stack>#include<queue>#include<algorithm>#include<numeric>#include<functional>using namespace std;typedef long long ll;const int maxn = 25;const double PI=acos(-1.0);int n;double ans;struct Node{    double x,y,r;}node[maxn];double dis(Node a,Node b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}double solve(Node a,Node b){    double d=dis(a,b);    if(d>=a.r+b.r)        return 0;    else        if(d<=fabs(a.r-b.r))        {            double mn=min(a.r,b.r);            return PI*mn*mn;        }    double ang1=acos((a.r*a.r+d*d-b.r*b.r)/(2.0*d*a.r));    double ang2=acos((b.r*b.r+d*d-a.r*a.r)/(2.0*d*b.r));    double area=a.r*a.r*ang1+b.r*b.r*ang2-d*a.r*sin(ang1);    return area;}int check(){int flag = 1;for(int i = 1; i <= n; i++){if(solve(node[0],node[i]) < node[i].r * node[i].r * PI*0.5){flag = 0;break;}}return flag;}double two(){double l = 0.0,r = 50000.0;while(r - l > 1e-8){double mid = (l+r) / 2.0;node[0].r = mid;if(check())r = mid;elsel = mid;}return l;}int main(void){int T,i;scanf("%d",&T);while(T--){scanf("%d",&n);for(i = 1; i <= n; i++){scanf("%lf%lf%lf",&node[i].x,&node[i].y,&node[i].r);}ans = 50000.0;for(i = 1; i <= n; i++){node[0].x = node[i].x;node[0].y = node[i].y;ans = min(ans,two());}printf("%.4lf\n",ans);}return 0;}