문제 보기 · Level 1 · PCCP 기출문제 1번 · 정답률 46% · 푼 사람 18,849명 (2026-09-30 기준)1
문제
붕대 감기는 1초마다 체력을 x씩 회복하고, t초를 연속으로 채우면 y를 더 회복한다. 체력은 최대 체력을 넘지 않는다. 공격을 받으면 피해만큼 체력이 줄고, 그 순간에는 회복하지 못하며, 연속 시간이 0으로 돌아간다. 마지막 공격 직후 체력을 돌려준다. 도중에 체력이 0 이하가 되면 −1을 돌려준다.
- t ≤ 50, x ≤ 100, y ≤ 100
- 최대 체력 ≤ 1,000
- 공격 최대 100번, 공격 시각 ≤ 1,000, 시각 순으로 정렬됨
풀이
막히면 한 단계씩 펼친다.
필요한 개념
구현과 시뮬레이션: 1초씩 시간을 흘리며 체력과 연속 시간이라는 두 상태를 규칙대로 바꾼다.
1단계 · 작은 예로 손으로 풀기
붕대 t = 3, x = 1, y = 2, 최대 체력 10, 공격 [(2초, 4), (7초, 3)]
| 초 | 일어난 일 | 연속 | 체력 |
|---|---|---|---|
| 0 | 시작 | 0 | 10 |
| 1 | 회복 +1 (최대 10) | 1 | 10 |
| 2 | 공격 −4, 연속 초기화 | 0 | 6 |
| 3 | +1 | 1 | 7 |
| 4 | +1 | 2 | 8 |
| 5 | +1, 연속 3초 달성 +2, 연속 초기화 | 0 | 11 → 10 |
| 6 | +1 (최대 10) | 1 | 10 |
| 7 | 공격 −3 | 0 | 7 |
마지막 공격 직후 체력은 7이다.
2단계 · 가장 단순한 방법과 그 속도
1초부터 마지막 공격 시각까지 1초씩 시뮬레이션한다. 마지막 공격이 최대 1,000초라 1,000번이면 끝난다. 그대로 해도 넉넉하다.
3단계 · 핵심 아이디어
기억할 상태는 둘뿐이다. 체력과 연속 시간(지금까지 끊기지 않고 감은 초)이다. 매초 둘 중 하나가 일어난다.
- 공격이 있는 초: 체력에서 피해를 빼고, 연속 시간을 0으로 한다. 회복은 없다. 체력이 0 이하면 바로 −1.
- 공격이 없는 초: 연속 시간 +1, 체력 +x. 연속 시간이 t가 되면 체력 +y, 연속 시간 0. 마지막에 체력을 최대 체력으로 자른다.
“이 초에 공격이 있나”를 빨리 보려고 공격을 {시각: 피해} 딕셔너리로 만든다.
4단계 · 코드 흐름
- t, x, y를 꺼내고, 체력 = 최대 체력, 연속 = 0으로 둔다.
- 공격을 시각 → 피해 딕셔너리로 만든다.
- 1초부터 마지막 공격 시각까지:
- 공격이 있으면 체력 −피해, 연속 = 0. 체력 ≤ 0이면 −1을 돌려준다.
- 없으면 연속 +1, 체력 +x. 연속이 t면 체력 +y, 연속 = 0. 체력 = min(체력, 최대).
- 체력을 돌려준다.
5단계 · 파이썬 코드
def solution(bandage, health, attacks):
t, x, y = bandage
hp, streak = health, 0
attack_at = {when: dmg for when, dmg in attacks} # 시각 → 피해
last = attacks[-1][0] # 마지막 공격 시각
for time in range(1, last + 1):
if time in attack_at:
hp -= attack_at[time]
streak = 0
if hp <= 0:
return -1
else:
streak += 1
hp += x
if streak == t:
hp += y
streak = 0
hp = min(hp, health)
return hp
t, x, y = bandage: 세 칸짜리 리스트를 세 이름에 나눠 담는다.{when: dmg for when, dmg in attacks}: 공격 목록을 딕셔너리로 바꾸는 컴프리헨션이다.attacks[-1][0]: 마지막 공격의 시각이다. 공격은 시각 순으로 주어진다.min(hp, health): 최대 체력을 넘지 않게 자른다.
6단계 · 실행 추적
1단계의 표가 코드의 반복과 한 줄씩 대응한다. time이 1~7일 때 각 줄의 streak와 hp가 표의 “연속”과 “체력”이다. 5초에 streak == t가 되어 +2를 받고, min으로 11이 10이 된다.
7단계 · 복잡도와 흔한 실수
마지막 공격 시각 T만큼 도니 \(O(T)\)다. 공격 사이의 빈 시간을 한 번에 계산하면(빈 시간 g초면 회복 g·x + (g // t)·y) 공격 수만큼으로 줄일 수 있다. 다만 이 제한에서는 필요 없다.
- 체력을 최대 체력으로 자르지 않는다.
- 공격받은 초에도 회복한다.
- 연속 t초를 채운 뒤 연속 시간을 0으로 되돌리지 않는다. 그러면 추가 회복을 한 번만 받는다.
- 체력이 0 이하가 된 뒤에도 계속 회복시킨다. 죽으면 바로 −1이다.
-
프로그래머스 스쿨, “[PCCP 기출문제] 1번 / 붕대 감기” (https://school.programmers.co.kr/learn/courses/30/lessons/250137), 2026-09-30 조회. ↩