nashidos’s diary

アルゴリズムとか機械学習とか色々

Pythonで余弦定理の問題を解いていく-ABC168

競技プログラミングではしばしば数学の知識が問われる問題が出されることがあります。

今回は高校で習う余弦定理を利用して解ける問題をPythonで解いていきます。

余弦定理

f:id:nashidos:20200603204604p:plain
余弦定理は一言で説明すると2つの辺の長さと1つの内角がわかっていれば、もう一つの辺の長さを求めることができるという定理です。

式で表すと以下の通りです。

  •  a^2 = b^2 + c^2 − 2bc cosα
  •  b^2 = c^2 + a^2 − 2ca cosβ
  •  c^2 = a^2 + b^2 − 2ab cos γ

Pythonではmathモジュールで三角関数の計算をすることができます。

例題

余弦定理で解ける問題として以下の問題を取り扱います。
atcoder.jp

問題文

時針と分針の長さがそれぞれ A センチメートル、Bセンチメートルであるアナログ時計を考えます。
時針と分針それぞれの片方の端点は同じ定点に固定されており、この点を中心としてそれぞれの針は一定の角速度で時計回りに回転します。時針は 12時間で、分針は 1 時間で 1周します。
0時ちょうどに時針と分針は重なっていました。ちょうど H 時 M 分になったとき、2 本の針の固定されていない方の端点は何センチメートル離れているでしょうか。

制約
  • 入力はすべて整数
  • 1≤A,B≤1000
  • 0≤H≤11
  • 0≤M≤59

実装

この問題は時針と分針がそれぞれ1時間または1分間でどれだけ進むかについて考えなければいけません。

時針は12時間で一周するので1時間あたり30度進み、1分間あたり0.5度進みます。

分針は60分で一周するので1分あたり6度進みます。

このことから1分あたり時針は分針に5.5度近づくもしくは遠ざかるということがわかります。

なので、内角は h*30 - m*5.5で求めることができます。

あとは余弦定理に落とし込むだけです。

import math
a,b,h,m = map(int,input().split())
print((a**2+b**2-2*a*b*math.cos(math.radians(h*30 - m*5.5)))**0.5)

まとめ

今回は余弦定理の問題をPythonで解いてみましたが、余弦定理以外にも内角を求めるところで考える力が少し必要だったかもしれません。

普段あまり三角関数を使わないので忘れかけていましたが、今後は忘れないように適度にアウトプットしようと思いました。

おわり