幾何ライブラリでOMCをシバく

ごめんなさい
幾何ライブラリはここ(いろいろな記事を参照して作りました)
https://github.com/tko919/library/blob/master/math/geometry.cpp

ex1:OMC012-E

Link:http://onlinemathcontest.com/contests/omc012/tasks/omc012_e
ABを決め打ちでにぶたんし、DGの距離によって解の区間を絞ります
何言ってるか分かりづらいと思うのでコード(テンプレート等は省略)

int main(){
   P b(0,0),e(3,0),f(8,0),c(12,0);
   double lb=6,rb=100;
   rep(_,0,60){
      double mid=(lb+rb)/2.;
      P a(6,sqrt(mid*mid-6*6));
      Circle C=Circumcircle(a,e,f);
      auto ad=Intersection(C,Line(a,b));
      auto ag=Intersection(C,Line(a,c));
      P d,g;
      if(abs(ad[0]-a)<eps)d=ad[1];
      else d=ad[0];
      if(abs(ag[0]-a)<eps)g=ag[1];
      else g=ag[0];
      if(norm(d-g)>39)rb=mid;
      else lb=mid;
   }
   printf("%.12f\n",lb);
   return 0;
}

実行すると"7.855844048496"と出力されました
これをWolframAlphaに投げると...

f:id:tk0_math:20201227165145p:plain


f:id:tk0_math:20201227165208p:plain
✌('ω'✌ )三✌('ω')✌三( ✌'ω')✌


もう一問やります

ex2:OMC013-F

Link:http://onlinemathcontest.com/contests/omc013/tasks/omc013_f
∠BCAは逆回りなことに注意して書きます

int main(){
   P d(0,0),e(1,0),c(9,0);
   double lb=4.5,rb=100;
   rep(_,0,60){
      double mid=(lb+rb)/2.;
      P b(4.5,-sqrt(mid*mid-4.5*4.5));
      Line l(b,(c-b)*P(0,1)+b);
      double theta=arg(c,e,b);
      Line ca(c,rot(b-c,-theta)+c);
      P a=Intersection(l,ca);
      double bac=arg(b,a,c),adc=arg(a,d,c);
      if(bac+adc>M_PI)rb=mid;
      else lb=mid;
   }
   printf("%.12f\n",lb);
   return 0;
}

総括

競プロでズルするのは楽しいか?
面積とかにも対応できるので、多分他の問題でも脳死で解けるはず
サジェストも出来ればコード上で実現したいけど、解の表現が複雑だと辛そうですね...(a+b*sqrt(c)/d とか)(いいアルゴリズムがあったら教えてください)