직각삼각형의 빗변(hypotenuse)과 넓이(area)가 주어졌을 때, 해당 조건을 만족하는 삼각형의 밑변(base)과 높이(height)를 구하는 문제입니다. 만약 주어진 값으로 직각삼각형을 만드는 것이 불가능하다면 False를 반환해야 합니다.
예를 들어, 입력이 hypo = 10, area = 24라면 출력은 (6, 8)이 됩니다. 실제로 밑변이 6, 높이가 8인 삼각형은 빗변이 √(36 + 64) = 10이고 넓이는 0.5 × 6 × 8 = 24로 조건을 정확히 만족합니다.
문제 해결 접근 방식
핵심 아이디어는 다음과 같습니다. 빗변이 고정되어 있을 때 삼각형의 넓이는 밑변에 따라 연속적으로 변하므로, 이분 탐색(Binary Search)을 활용해 목표 넓이를 만족하는 밑변을 찾을 수 있습니다.
알고리즘 단계
hypo_sq:= 빗변의 제곱 (hypo * hypo)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- 현재
base로 계산한 넓이가 목표area보다 크거나 같으면right := base - 그렇지 않으면
left := base
height:= √(hypo_sq − base²) 를 계산한 후 가장 가까운 정수로 반올림base도 가장 가까운 정수로 반올림base와height반환
예제 코드
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))입력
hypo = 10, area = 24
출력
(6, 8)
코드 설명
calculate_area(b, h): 피타고라스 정리(hei = √(h² − b²))로 높이를 구한 뒤, 넓이0.5 × b × hei를 반환하는 보조 함수입니다.s = √(hypo² / 2): 빗변이 고정된 직각삼각형에서 넓이가 최대가 되는 경우는 밑변과 높이가 같은 경우이므로, 탐색 범위의 상한으로 사용됩니다.- 이분 탐색의 오차 허용치를
0.000001로 설정하여 충분히 정밀한 결과를 얻습니다. - 마지막에 결과를 정수로 반올림하여 깔끔한 형태의 답을 반환합니다.
이 방법의 시간 복잡도는 이분 탐색 반복 횟수에 비례하며, 오차 범위가 고정되어 있으므로 사실상 O(log(maxArea/ε)) 수준으로 매우 효율적입니다.