1. 문제 이해
붕대 감기 기술을 사용하여 체력을 회복하면서, 주어진 공격 패턴에 따라 체력이 감소하는 과정을 시뮬레이션하는 문제입니다.
조건에 맞춰 연속 성공 시 추가 회복을 고려해야 하며, 체력이 0 이하가 되면 즉시 종료해야 합니다.
2. 해결 접근 방식
- 공격 데이터를 빠르게 조회하기 위해 attack_dict (딕셔너리)를 생성합니다.
- 시간을 1초 단위로 진행하며 공격 여부를 체크합니다.
- 공격이 없을 경우 체력을 회복하며 연속 성공 시간을 증가시킵니다.
- 공격이 있으면 체력을 감소시키고, 붕대 감기를 실패 처리합니다.
- 체력이 최대 체력을 초과하지 않도록 보정합니다.
- 체력이 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. 시간 복잡도 분석
📌 주요 연산
- attack_dict 생성 → O(N)
- for time in range(attacks[-1][0] + 1): → O(T) (공격이 끝나는 시간까지 루프)
- if time in attack_dict: → O(1) (딕셔너리 조회)
- 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 반환