三分探索?
TopCoder SRM421の、DIV1 Level1問題(万有引力の平衡点を求めるやつ)について。
この問題の骨子は、単調関数の零点を二分探索で求める、というものでした。
ですが、同じ部屋で2人が見慣れない解き方をしていて気になりました。
その1 その2(TopCoderのログインが必要)
この二つの解答は、二分探索とはちょっと違った「三分探索」とも呼ぶべき方法で解いてあります。
簡略化するとこんな感じ。
double EPS = 1e-10; double left = x[i]; double right = x[i+1]; while(right - left > EPS){ double dif = (right - left) / 3; double vl = calc(left + dif); double vr = calc(right - dif); if(abs(vl) > abs(vr)){ left = left + dif; }else{ right = right - dif; } } return left;
左端から右端に向かって1/3進んだところの値と2/3進んだところの値を計算して、絶対値が大きい方の端を縮めています。
確かにこの方法でも計算できるんですが、1回の繰り返しで区間が2/3にしか縮まらないので効率は少し悪いです。それから、calc()が単調の場合にしか使えないアルゴリズムでもあり、とくに利点はなさそう。
上位30人のコードを見てもこの方法でやっていた人はいませんし、単に「変な解き方をした人がたまたま同じ部屋に2人重なった」というだけかなと思うのですが、どうなんでしょう。単に僕が知らなかっただけで、何らかの利点がある?