Pythonで斜辺と面積から直角三角形が成立するか判定し、底辺と高さを求める方法
問題概要
直角三角形の斜辺と面積が与えられたとき、その三角形の底辺と高さを求めます。条件を満たす三角形が存在しない場合は False を返します。
例えば、斜辺が 10、面積が 24 の場合、答えは (6, 8) となります。
解法のアプローチ
この問題は二分探索(バイナリサーチ)を使うことで効率的に解けます。考えるポイントは次の通りです。
- 直角三角形の面積は「0.5 × 底辺 × 高さ」で表されます。
- 斜辺が固定されているとき、底辺と高さが等しい(どちらも 斜辺 ÷ √2)ときに面積が最大になります。
- そのため、理論上の最大面積を与える値 s = √(hypo² / 2.0) を求め、指定された面積がこれを超えていれば、その斜辺では三角形が成立しません。
- 成立する場合は、底辺の候補を 0 から s の範囲で二分探索し、目的の面積に対応する底辺を絞り込みます。
アルゴリズムの手順
- hypo_sq := hypo × hypo(斜辺の2乗)を計算する
- s := √(hypo_sq / 2.0) を求める
- maxArea := 底辺 s・斜辺 hypo から計算される面積を求める
- area > maxArea であれば
Falseを返す - left := 0.0、right := s で初期化する
- |right − left| > 0.000001 の間、以下を繰り返す:
- base := (left + right) / 2.0
- calculate_area(base, hypo) ≥ area なら right := base、そうでなければ left := base
- height := round(√(hypo_sq − base²)) として高さを求め、四捨五入する
- base も四捨五入して整数にする
- base と height を返す
実装例(Pythonコード)
以下が実際の実装例です。
from math import sqrt
def calculate_area(b, h):
hei = sqrt(h*h - b*b)
return 0.5 * b * hei
def solve(hypo, area):
hypo_sq = hypo * hypo
s = sqrt(hypo_sq / 2.0)
maxArea = calculate_area(s, hypo)
if area > maxArea:
return False
left = 0.0
right = s
while abs(right - left) > 0.000001:
base = (left + right) / 2.0
if calculate_area(base, hypo) >= area:
right = base
else:
left = base
height = round(sqrt(hypo_sq - base*base))
base = round(base)
return base, height
hypo = 10
area = 24
print(solve(hypo, area))
実行結果
入力
10, 24
出力
(6, 8)
計算量について
収束の許容誤差を ε = 0.000001 とした場合、二分探索の反復回数はおよそ log₂(s / ε) 回程度に収まり、非常に高速です。時間計算量は O(log(s/ε))、空間計算量は O(1) となります。
-
Pythonでベクトルxを90度回転・加算してベクトルyに到達できるか判定するアルゴリズム
2次元平面上に3つのベクトル x、y、z があるとします。ベクトル x を起点として、「90度(時計回り)の回転」または「ベクトル z の加算」を必要な回数だけ繰り返すことで、ベクトル y に到達できるかどうかを判定するのがこの問題です。 たとえば、入力が x = (-4, -2)、y = (-1, 2)、z = (-2, -1) である場合、出力は True になります。x に対して z を加算する操作と 90 度の時計回り回転を組み合わせることで、y = (-1, 2) の位置に到達できるからです。 解法のアプローチ この問題は、次の手順に沿って解くことができます。 1. util()
-
Pythonで点のリストから作れる最大の三角形の面積を求める方法
平面上に与えられた点のリストの中から、任意の3点を選んで作ることができる三角形のうち、最も大きな面積を持つものを求める問題です。例えば、入力が [[0,0],[0,1],[1,0],[0,2],[2,0]] の場合、出力は 2 となります。解法のアプローチこの問題は、すべての3点の組み合わせについて三角形の面積を計算し、その最大値を求めることで解けます。手順は以下の通りです。結果を格納する変数 res を 0 で初期化する点のリストのサイズを N とする三重ループで、i、j、k の3つのインデックスの組み合わせをすべて列挙する(i < j < k)各組み合わせに対して、3点の座標