题意: 给出三个圆,要求找一点使得该点看三个圆的角度尽量相等,如果相等取最大角度
分析: 首先该点肯定存在于三个圆心所组成的三角形内部,并且具有极值,在三角形外部也存在这样的点,但是一定不满足最优解条件,那么根据这一点,我们去三角形的外圆心,从该点搜索极值,根据角度的方差构造估价函数
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cmath> #include<time.h> using namespace std; #define eps 1e-7 int dir[][5]= {{0,1},{0,-1},{1,0},{-1,0}}; struct node { double x,y,r; node(double _x,double _y){x=_x,y=_y,r=0;} node(){} } p[3]; double dis(double x,double y,int i) { return sqrt((x-p[i].x)*(x-p[i].x)+(y-p[i].y)*(y-p[i].y)); } double F(double x,double y) { double angle[3]; double sum=0; for(int i=0; i<3; i++) angle[i]=dis(x,y,i)/p[i].r,sum+=angle[i]; sum/=3; double k=0; for(int i=0; i<3; i++) k+=(angle[i]-sum)*(angle[i]-sum); return k; } node waixin(node a,node b,node c) { double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1*a1 + b1*b1)/2; double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2*a2 + b2*b2)/2; double d = a1*b2 - a2*b1; return node(a.x + (c1*b2 - c2*b1)/d, a.y + (a1*c2 -a2*c1)/d); } int main() { for(int i=0; i<3; i++) scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].r); node temp=waixin(p[0],p[1],p[2]); double x=temp.x; double y=temp.y; int len=1; double delte=0.5; double t=1; for(int i=0; i<=100000; i++) { double k=F(x,y); if(k<=eps) continue; int flag=0; double tx=x,ty=y,tk=k; for(int j=0; j<4; j++) { double _x=x+t*dir[j][0]; double _y=y+t*dir[j][1]; double _k=F(_x,_y); if(_k<tk) { tk=_k; tx=_x; ty=_y; flag=1; } } if(flag) x=tx,y=ty,k=tk; else t*=delte; } double ansx=x,ansy=y; double k=F(x,y); if(k<=eps) printf("%.5f %.5f\n",ansx,ansy); return 0; }