codeforces 2c Commentator problem
如果2个圆半径相同,选取的点一定在一条直线上,如果2个圆半径不同,选取的点一定在一个圆上,根据这个可以求出他们的交点,可行的交点不会超过2个,然后从中选出角度比较大的点。
所以本题是计算几何或者还可以用模拟退火,调参数调到死。
#include<bits/stdc++.h>
using namespace std;
double x[3],y[3],r[3];
double calc(double x1,double y1){
double ret=0;
double t[3];
for(int i=0;i<3;i++)
t[i]=sqrt((x1-x[i])*(x1-x[i])+(y1-y[i])*(y1-y[i]))/r[i];
ret=(t[0]-t[1])*(t[0]-t[1])+(t[1]-t[2])*(t[1]-t[2])+(t[2]-t[0])*(t[2]-t[0]) ;
return ret;
}
int main(){
for(int i=0;i<3;i++)
cin>>x[i]>>y[i]>>r[i];
double tx=0,ty=0;
for(int i=0;i<3;i++)
tx+=x[i]/3,ty+=y[i]/3;
double s=1;
while (s>1e-6){
if(calc(tx,ty)>calc(tx+s,ty))
tx+=s;
else if(calc(tx,ty)>calc(tx-s,ty))
tx-=s;
else if(calc(tx,ty)>calc(tx,ty+s))
ty+=s;
else if(calc(tx,ty)>calc(tx,ty-s))
ty-=s;
else s*=0.7;
}
if(calc(tx,ty)<1e-5)
cout<<fixed<<setprecision(5)<<tx<<" "<<ty<<endl;
return 0;
}