Open-air shopping malls(hdu 3264 二分+求两圆相交面积
题解:每个圆作为大圆圆心遍历过去
求每个圆心 满足条件的最小半径 在所有最小半径里找min
#include<bits/stdc++.h> using namespace std; #define pi acos(-1.0) double x[22],y[22],r[22]; /*1 2 0 0 1 2 0 1 */ int n; double mj(double x1,double y1,double r1,double x2,double y2,double r2)//相交面积 ,有模板的,刚开始我还自己写 错的 {//一开始返回成bool了 double d = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); if (d >= r1+r2) return 0; if (r1>r2) { double tmp = r1; r1 = r2; r2 = tmp; } if(r2 - r1 >= d) return pi*r1*r1; double ang1=acos((r1*r1+d*d-r2*r2)/(2*r1*d)); double ang2=acos((r2*r2+d*d-r1*r1)/(2*r2*d)); return ang1*r1*r1 + ang2*r2*r2 - r1*d*sin(ang1); } bool check(double xx,double yy,double rr) { int i; for(i=0;i<n;i++) { if(mj(xx,yy,rr,x[i],y[i],r[i])*2<r[i]*r[i]*pi)return 0; } return 1; } double calc(double xx,double yy)//二分找满足条件的最小半径 { int i; double l=0,r=20000; while(r-l>1e-6) { double mid=(l+r)/2.0; if(check(xx,yy,mid))r=mid; else l=mid; } return l; } void work() { int i; double minn=1e9; for(i=0;i<n;i++) { minn=min(minn,calc(x[i],y[i]));//以这个为圆心 } printf("%.4f\n",minn); } int main() { int i,t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i<n;i++) { scanf("%lf%lf%lf",&x[i],&y[i],&r[i]); } work(); } return 0; }