Aizu Online Judge(AOJ)が提供している「プログラミング入門」(ITP1)の10_B問題をC++とPython で解いてみました。
ITP1 のトピック10では、数学関数について学びます。「基礎的な数学関数を学習します。」とあります。この学習コースを通じて、Python に慣れていきたいと考えています。
問題(10_B: Triangle)
問題はリンク先をご覧ください。
三角形に関する値を計算する問題です。高校数学で履修した範囲の知識(sin、cos、三角形の面積、余弦定理、弧度法)を使います。
高校数学の復習
三角形の辺を a、b、c として、その辺の反対にある角を A、B、C とする(A は、辺 b と辺 c の間にある角を指す)。
三角形の面積
この三角形の面積 S は、以下となる。
$$S = \frac{1}{2} a b \sin C = \frac{1}{2} b c \sin A = \frac{1}{2} c a \sin B$$
余弦定理
角 C が直角(90度)になっている場合、次の三平方の定理が成立する。
$$c^2 = a^2 + b^2$$
次の余弦定理は、この関係を拡張した式になっている。
$$c^2 = a^2 + b^2 – 2 b c \cos A$$
度数法と弧度法
日常的には、角度を表現するため度数法を使っています。直角が90度となります。度数法で180度が、弧度法で円周率の $\pi$ となります。C++ や Python で使える三角関数(sin、cos など)は、弧度法で値を与えます。
弧度法の値 rad は、度数法の値 deg を使って以下のように変換できます。
$$rad = \pi / 180 \times deg$$
解答案
C++ プログラム例(ITP1 10_B)
度数法で与えられた C を弧度法の値 rad_C に変換しています。M_PI は、math.h(cmath)で定義されている円周率の値になります。
以下が C++ のプログラムとなります。
#include <iostream>
#include <ios> // fixed
#include <iomanip> // setprecision
#include <cmath>
using namespace std;
int main()
{
double a, b, C;
cin >> a >> b >> C;
double rad_C, c, S, L, h;
rad_C = C * M_PI / 180.0;
c = sqrt(a * a + b * b - 2.0 * a * b * cos(rad_C));
S = a * b * sin(rad_C) / 2.0;
L = a + b + c;
h = b * sin(rad_C);
cout << fixed << setprecision(5);
cout << S << endl;
cout << L << endl;
cout << h << endl;
return 0;
}
Python プログラム例(ITP1 10_B)
Python では、弧度法に変換する関数 math.radians が用意されています。
import math
a, b, C = map(float, input().split())
c = math.sqrt(a ** 2.0 + b ** 2.0 - 2.0 * a * b * math.cos(math.radians(C)))
S = a * b * math.sin(math.radians(C)) / 2.0
L = a + b + c
h = b * math.sin(math.radians(C))
print(f"{S:.5f}", f"{L:.5f}", f"{h:.5f}", sep="\n")
上記プログラムは、すべて AOJ で「AC(Accepted=正解)」と判定されます。
最後に
主に高校で履修する数学Ⅰの三角形についての公式を使いました。公式が分かれば、プログラムで表現することは、それほど難しくない問題でした。
引き続き、ITP1 の問題を紹介していきます。