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;}