メモ帳がわり

個人的なメモを残します。主に競プロ

【典型90問】018 - Statue of Chokudai(★3)

問題リンク

解法

問題文を読んだだけでは、観覧車がどのような動きをしているのかわかりにくいが、図を書いてみると、中心を(0, 0, L/2)とした半径2/Lの円周上を動いていることがわかる。
まず、与えられた時間の時の現在地の座標が知りたい。
中心を(0, 0, L/2)としたままだとわかりにくいので、中心をO(0, 0, 0)へ移動させて考える。
現在地を点P(0, y, z)として、OPとy軸の正の向きとなす角をαとした時、$ sinα = \frac{2z}{L}, cosα =\frac{2y}{L} $ であるから、$ z = sinα\frac{L}{2}, y = cosα\frac{L}{2} $ となる。
現在時刻をtとすると、t=0のとき、α=270°、t=nのとき、α=270°-360°×n/T となるので、現在地の座標を求めることができた。 ただし、最初に平行移動したので元に戻しておく。
これで、答えとなる仰角θを求める準備ができた。
高橋直大像の座標をQ(X, Y, 0)とすると、 $ tanθ=\frac{z}{\sqrt{X^{2}+(Y-y)^{2}}} $ であるから、これをatanを使ってラジアンに変換し、度数法に直せば答えになる。

実装

void solve(long long T, long long L, long long X, long long Y, long long Q, std::vector<long long> E) {
    REP (i, Q) {
        // 現在地を算出
        long double angle = 270.0 - 360.0 * ((double)E[i] / T);
        long double radian = angle * PI / 180.0;
        long double y = cosl(radian) * (L/2.0);
        long double z = sinl(radian) * (L/2.0) + (L/2.0);

        // 答えを求める
        long double tan_theta = z / (sqrt(pow(X, 2) + pow(Y-y, 2)));
        long double radian_ans = atanl(tan_theta);
        long double ans = radian_ans * 180 / PI;
        
        cf(ans)
    }
}