hdo3264

来源:互联网 发布:还原软件哪个好 编辑:程序博客网 时间:2024/06/03 13:01

这题刚开始没看懂大伞的center是什么,看了别人的解题思路,才知道是每个mall的圆心。 大家都用 二分+两圆相交。枚举一个半径,看是否能覆盖所有圆 面积的1/2以上,然后运用二分思想,求出最小的半径。 在这里粘一下别人的代码。 我有个想法:对于每一个center,找出与center距离最远的那个mall的圆心,求出能使两圆相交面积为1/2的最小半径,既然最远的点都满足条件了,那么其他的点一定也满足。代码过两天粘。


二分+两圆相交:

#include <queue>#include <stack>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <iostream>#include <limits.h>#include <string.h>#include <string>#include <algorithm>using namespace std;const double MAX = 1e6;const double eps = 1e-6;const double pi=acos(-1.0);bool dy(double x,double y){return x > y + eps;}// x > y bool xy(double x,double y){return x < y - eps;}// x < y bool dyd(double x,double y){ return x > y - eps;}// x >= y bool xyd(double x,double y){return x < y + eps;} // x <= y bool dd(double x,double y) {return fabs( x - y ) < eps;}  // x == ystruct point{double x,y;};struct circle{       double  r;       point center;}p[21];double disp2p(point a,point b) {return sqrt( ( a.x - b.x ) * ( a.x - b.x ) + ( a.y - b.y ) * ( a.y - b.y ) );}double crossProduct(point a,point b,point c)//向量 ac 在 ab 的方向 {return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y);}double cirarea(circle c){       return pi*c.r*c.r;}double interarea(circle a,circle b){   double d=disp2p(a.center,b.center);   if(d>=a.r+b.r)return 0;   double r=a.r>b.r?b.r:a.r;   if(d<=fabs(a.r-b.r))return pi*r*r;   double angle1=acos((a.r*a.r+d*d-b.r*b.r)/2.0/a.r/d);   double angle2=acos((b.r*b.r+d*d-a.r*a.r)/2.0/b.r/d);   double ans=0;   ans-=d*a.r*sin(angle1);   ans+=angle1*a.r*a.r+angle2*b.r*b.r;//S=S1+S2-S3     return ans;}bool call(int n,double rr){     for(int i=0,j;i<n;i++)     {             circle temp;             temp=p[i];             temp.r=rr;             for( j=0;j<n;j++)             if(interarea(temp,p[j])<cirarea(p[j])/2.0) break;             //if(j==n&&interarea(temp,p[j])>=cirarea(p[j])/2.0))             if(j==n)             return true;     }     return false;}int main(){    int t,n;    double r;    while(cin>>t)    {        while(t--)        {            cin>>n;            for(int i=0;i<n;i++)            cin>>p[i].center.x>>p[i].center.y>>p[i].r;            double left=0,right=MAX,mid;            while(xy(left,right))            {                   mid=(left+right)/2;                   if(call(n,mid))  right=mid;                   else left=mid;            }            r=right;            printf("%.4lf\n",r);        }    }    return 0;}