ryo’s blog

日々学んだことをまとめています.

競プロ典型90問 018(★3) 三角関数

018 - Statue of Chokudai(★3)

問題

平面 x = 0 上に、高さ L の T 分で一周する観覧車がある。

xy 平面が水平で z が垂直。

  • 0 分後の座標は (0,0,0)
  • \frac{T}{4}分後の座標は (0,-\frac{L}{2},\frac{L}{2})
  • \frac{T}{4}分後の座標は (0,0,L)
  • \frac{3T}{4}分後の座標は (0,\frac{L}{2},\frac{L}{2})

銅像(X,Y,0)にある。

以下の形式の質問が Q 個与えられるので順に求める。

  • i 個目の質問では、E_i 分後における、銅像の俯角を求める。

解法

三角関数を色々使う。

sin, cosを使うときはラジアンでの角度が引数になっている。

そのため a 度における sin の値を求めたい場合、 sin(3.1415...*a/180.0)にする必要がある。

銅像と観覧車の水平距離を A, 観覧車の高さを B とする。

求める俯角は atan2(B,A)となる。

観覧車の座標を (0,sy,sz)とするとき、

水平距離は、 \sqrt { px ^ 2 + ( sy - py ) ^ 2 }

高さは、sz となる。

所感

数学ちっくな問題は、苦手なので勉強しなければ。。

三角関数など、あまり使う機会がないので面白かったけど難しいー。

コード

#include <bits/stdc++.h>
#define rep(i,n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;
struct fast_ios { fast_ios(){ cin.tie(nullptr), ios::sync_with_stdio(false), cout << fixed << setprecision(20); }; } fast_ios_;
const int INF = (int)1e9;
const ll INFL = (ll)1e18;
const int MOD = 1e9 + 7;
const double EPS = 1e-10;
int dx[]={0, 0, -1, 1};
int dy[]={1, -1, 0, 0};
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }

const double PI = acos(-1);
double t, l, x, y, e, q;

double solve(double d)
{
    double cx, cy, cz, d1, d2, fukaku;
    cx = 0; // x座標
    cy = -(l / 2.0) * sin(d / t * 2.0 * PI); // y座標
    cz = (l / 2.0) - (l / 2.0) * cos(d / t * 2.0 * PI); // z座標
    d1 = sqrt(pow((cx - x),2) + pow((cy - y), 2)); // 水平距離
    d2 = cz; // 観覧車の高さ
    fukaku = atan2(d2, d1);
    return fukaku * 180.0L / PI;
}

int main()
{
    cin >> t;
    cin >> l >> x >> y;
    cin >> q;
    rep(i,q)
    {
        cin >> e;
        cout << solve(e) << endl;
    }
    return 0;
}