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도 가장 가까운 정수로 반올림
  • baseheight 반환

예제 코드

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/ε)) 수준으로 매우 효율적입니다.