Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python으로 빗변과 넓이가 주어졌을 때 직각삼각형 성립 여부 확인하기

직각삼각형의 빗변(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/ε)) 수준으로 매우 효율적입니다.