Codeforces Round #330 (Div. 1) B. Max and Bike
解法
問題の様にセンサを取り付けると, センサはサイクロイドと呼ばれる軌道を描きます。
d = f-s とすると, d の の部分の倍数の部分はどうなろうと関係ないので, 結局のところ調べるべき図形は以下のような部分だけになります。
は左右で等しくなるのが最適でしょう。
これらの情報が与えられた時, をどう求めるかを考えます。
図を見るとわかるように, です。 は計算できるので, この値になるように を調整したいですが, が単調増加関数であることを用いると, これは二分探索で求めることが出来ます。このようにして を求めます。すると, この区間の中で実際に走る距離は となります。
得た知見
- 問題の本質とは関係ないけど long double の出力を printf("%.10Lf\n", ans); ってやると変な数字が出るらしい
- 手元では普通に出力されるんだけどこどふぉではダメ
- なので double に戻してから printf を使うのが良さ気(long double で出力できる方法があったら教えて欲しいです)
typedef long long ll; typedef long double Real; const Real PI = acos(-1.0); int n, r, v; inline Real calc(Real theta) { return r*(theta-sin(theta)); } int main() { cin >> n >> r >> v; while (n--) { int s, f; scanf("%d%d", &s, &f); Real d = f-s; ll ni = d/(2*PI*r); Real D = (1+ni)*(2*PI*r) - d; if (D > 2*PI*r) D -= 2*PI*r; Real low = 0, high = PI; for (int i = 0; i < 60; i++) { Real med = (high+low) / 2; if (2*calc(med) > D) high = med; else low = med; } Real theta = (low+high)/2; d -= 2*r*sin(theta); double ans = d/v; printf("%.10lf\n", ans); } return 0; }