Codeforces 2 C. Commentator problem

問題

3つの円が与えられる。

それぞれの円に対して引いた2本の接線のなす角度が等しくなるような点の座標を求めよ。
複数ある場合は、角度が最大になる点を求め、存在しない場合は何も出力してはならない。

制約条件

座標の絶対値≦1000

方針

山登り法で収束するまでまわす。


評価関数は、それぞれの角度をa[i]としたときに(a[i]-a[j])^2で、
これを最小にする。
近傍は(x,y)に対して(x+1,y),(x-1,y),(x,y+1),(x,y-1)を取ればよい。

ソースコード

const int dy[]={-1,0,1,0},dx[]={0,-1,0,1};
const double PI=acos(-1.0);
const double EPS=1e-7;
P o[3];
double r[3];
double func(P p){
  double tmp[3];
  rep(i,3)tmp[i]=abs(p-o[i])/r[i];
  double res=0;
  rep(i,3)res+=(tmp[i]-tmp[(i+1)%3])*(tmp[i]-tmp[(i+1)%3]);
  return res;
}
void run(){
  P p(0,0);
  rep(i,3)cin>>o[i].real()>>o[i].imag()>>r[i], p+=o[i];
  p*=1.0/3;
  double l=1;
  rep(it,100000){
    double mn=1e12; int mnd;
    rep(d,4){
      P np=p+l*P(dy[d],dx[d]);
      double a=func(np);
      if(a<mn)mn=a, mnd=d;
    }
    p+=l*P(dy[mnd],dx[mnd]);
    l*=0.999;
  }
  if(func(p)<EPS)printf("%.9f %.9f\n",p.real(),p.imag());
}