본문 바로가기
카테고리 없음

프로그래머스 | Python | 단순구현, Hash | 붕대감기 (Lv.1)

by RuntimeSimple 2025. 2. 13.

1. 문제 이해

붕대 감기 기술을 사용하여 체력을 회복하면서, 주어진 공격 패턴에 따라 체력이 감소하는 과정을 시뮬레이션하는 문제입니다.

조건에 맞춰 연속 성공 시 추가 회복을 고려해야 하며, 체력이 0 이하가 되면 즉시 종료해야 합니다.


2. 해결 접근 방식

  1. 공격 데이터를 빠르게 조회하기 위해 attack_dict (딕셔너리)를 생성합니다.
  2. 시간을 1초 단위로 진행하며 공격 여부를 체크합니다.
  3. 공격이 없을 경우 체력을 회복하며 연속 성공 시간을 증가시킵니다.
  4. 공격이 있으면 체력을 감소시키고, 붕대 감기를 실패 처리합니다.
  5. 체력이 최대 체력을 초과하지 않도록 보정합니다.
  6. 체력이 0 이하로 떨어지는 경우 즉시 종료하고 -1을 반환합니다.

def solution(bandage, health, attacks):
    t, x, y = bandage  # t: 연속 성공 시간, x: 초당 회복량, y: 추가 회복량
    max_health = health  # 최대 체력 저장
    
    attack_dict = {attack[0]: attack[1] for attack in attacks}  # 공격 시간을 딕셔너리로 변환
    success_time = 0  # 연속 성공 시간

    for time in range(attacks[-1][0] + 1):  # 마지막 공격 시간까지 시뮬레이션
        if time in attack_dict:  # 공격이 있는 시간
            health -= attack_dict[time]  # 체력 감소
            success_time = 0  # 붕대 감기 실패로 초기화
            if health <= 0:  # 체력이 0 이하가 되면 즉시 사망
                return -1
        else:  # 붕대 감기 실행
            success_time += 1
            health += x  # 초당 회복량 적용
            if success_time == t:  # t초 연속 성공 시 추가 회복 적용
                health += y
                success_time = 0  # 연속 성공 초기화
            health = min(health, max_health)  # 체력이 최대 체력을 초과하지 않도록 보정

    return health  # 최종 체력 반환

3. 코드 설명

def solution(bandage, health, attacks):
  • bandage: [시전 시간, 초당 회복량, 추가 회복량] 정보가 들어 있는 리스트
  • health: 최대 체력
  • attacks: [[공격 시간, 피해량], ...] 형태의 리스트

📌 Step 1: 변수 초기화

    t, x, y = bandage  # t: 연속 성공 시간, x: 초당 회복량, y: 추가 회복량
    max_health = health  # 최대 체력 저장
  • t: 연속으로 성공해야 하는 시간
  • x: 초당 회복량
  • y: 추가 회복량
  • max_health: 체력이 최대 체력을 초과하지 않도록 하기 위한 변수

📌 Step 2: 공격 정보를 딕셔너리로 변환

    attack_dict = {attack[0]: attack[1] for attack in attacks}
  • 공격 시간을 빠르게 조회하기 위해 딕셔너리 attack_dict 생성→ {공격 시간: 피해량} 형태로 저장하여 O(1)으로 공격 여부 확인 가능

📌 Step 3: 시간별 체력 변화 시뮬레이션

    success_time = 0  # 연속 성공 시간 초기화

    for time in range(attacks[-1][0] + 1):  # 마지막 공격 시간까지 반복
  • success_time: 붕대 감기 연속 성공 시간을 추적
  • 0초부터 마지막 공격 시간까지 루프를 돌며 체력 변화를 시뮬레이션

📌 Step 4: 공격 여부 확인

        if time in attack_dict:  # 공격이 있는 경우
            health -= attack_dict[time]  # 체력 감소
            success_time = 0  # 붕대 감기 실패로 초기화
            if health <= 0:  # 체력이 0 이하가 되면 즉시 사망
                return -1
  • 공격이 있는 시간이라면, 체력 감소 및 연속 성공 초기화
  • 체력이 0 이하가 되면 즉시 사망 → 1 반환

📌 Step 5: 붕대 감기 진행

        else:  # 공격이 없는 경우
            success_time += 1
            health += x  # 초당 회복량 적용
  • 공격이 없는 시간이라면 체력을 초당 회복량만큼 증가
  • 연속 성공 시간을 1 증가

📌 Step 6: 연속 성공 시 추가 회복 적용

            if success_time == t:  # 연속 성공 시간이 t에 도달하면
                health += y  # 추가 회복량 적용
                success_time = 0  # 연속 성공 초기화
  • t초 동안 연속으로 붕대를 감으면 y만큼 추가 회복
  • 연속 성공이 초기화되며 다시 카운트 시작

📌 Step 7: 체력이 최대 체력을 초과하지 않도록 조정

            health = min(health, max_health)
  • 체력이 최대 체력을 넘지 않도록 보정 (최대 체력 유지)

📌 Step 8: 최종 체력 반환

    return health  # 모든 공격 이후 남은 체력 반환
  • 공격이 끝난 후 남아 있는 체력 반환
  • 중간에 체력이 0 이하가 되면 -1을 반환하며 종료

4. 시간 복잡도 분석

📌 주요 연산

  1. attack_dict 생성 → O(N)
  2. for time in range(attacks[-1][0] + 1): → O(T) (공격이 끝나는 시간까지 루프)
  3. if time in attack_dict: → O(1) (딕셔너리 조회)
  4. health = min(health, max_health) → O(1)

📌 전체 시간 복잡도

  • O(T + N) (T: 최대 공격 시간, N: 공격 개수)
  • 공격 개수가 많아도 O(N), 시간이 길어도 O(T)로 동작하여 효율적입니다.

🔷 5. 예제 풀이 (시뮬레이션)

입력 예제 1

bandage = [5, 1, 5]
health = 30
attacks = [[2, 10], [9, 15], [10, 5], [11, 5]]

출력: 5

시간 현재 체력 연속 성공 공격 설명

0 30 0 X 초기 상태
1 30 (+0) 1 X 최대 체력 유지
2 20 (-10) 0 O 공격받아 체력 감소
3 21 (+1) 1 X 회복 시작
4 22 (+1) 2 X  
5 23 (+1) 3 X  
6 24 (+1) 4 X  
7 30 (+6) 5 → 0 X 연속 성공 보너스
8 30 (+0) 1 X 최대 체력 유지
9 15 (-15) 0 O 공격받아 체력 감소
10 10 (-5) 0 O 공격받아 체력 감소
11 5 (-5) 0 O 공격받아 체력 감소

→ 결과: 5 (캐릭터 생존)


6. 최종 정리

딕셔너리를 활용하여 공격 정보를 빠르게 조회

붕대 감기 성공 시간을 체크하여 체력 회복 최적화

시간 순서대로 체력 변화를 시뮬레이션

O(T + N)으로 최적화된 시간 복잡도 유지

체력이 0 이하가 되면 즉시 -1 반환