Algorithm

[프로그래머스] [PCCP 기출문제] 1번 / 붕대 감기

비번변경 2024. 3. 1. 01:13

문제

문제 : https://school.programmers.co.kr/learn/courses/30/lessons/250137

 

어떤 게임에 붕대감기라는 기술이 있다.

붕대감기 기술은 t초 동안 실행되는데 1초마다 x만큼의 체력을 회복한다. 또한 t초 연속으로 붕대를 감으면 y만큼의 체력을 추가로 회복한다.

캐릭터가 붕대감기 기술을 쓰는 도중 몬스터에게 공격당하면 기술이 취소되며 체력을 회복할 수 없다. 기술이 취소되거나 기술이 끝나면 캐릭터는 즉시 붕대감기 기술을 재사용하며 연속 성공 시간이 초기화된다.

게임 캐릭터는 최대 health만큼의 체력을 가질 수 있다. 몬스터의 공격을 받으면 피해량만큼 캐릭터의 체력이 줄어들며, 현재 체력이 0 이하가 되면 죽는다.

 

붕대감기 기술의 시전 시간, 초당 회복량, 추가 회복량의 정보를 가진 bandage, 캐릭터의 최대 채력을 의미하는 health, 몬스터의 공격 시각과 피해량을 가진 attacks를 입력받아 캐릭터가 모든 공격이 끝난 후에도 생존하는지 남은 체력을 구하여라. 만약 캐릭터가 죽으면 -1을 반환한다.

 

 

예시

아래 값을 예시로 동작 방식을 정리하면 다음과 같다.

bandage = [5, 1, 5]	
 health = 30
attacks = [[2, 10], [9, 15], [10, 5], [11, 5]]	
 result = 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 5초 연속 성공해 체력 추가 회복
30(+0) 1 X 최대 체력
9 15(-15) 0 O  
10 10(-5) 0 O  
11 5(-5) 0 O  

 

 

구현

시작 시각부터 몬스터의 공격이 끝나는 시각까지 1초씩 반복문을 사용해 체력을 계산하는 방법도 있지만, 이 문제의 경우 몬스터가 공격하는 시각에 캐릭터의 체력을 계산하는 편이, 즉 attacks에 대해 반복문을 사용하는 편이 좀 더 간결한 코드를 작성할 수 있을 것 같았다.

 

고려할 부분은 아래와 같다.

1. attacks에 대해 반복문을 수행하므로 체력 감소는 항상 발생한다.

2. 초기 상태, 즉 처음 시작하는 시점에서는 체력 회복이 발생하지 않는다.

3. 회복량은 현재 시점과 이전 공격 시점의 차이가 아니라, 현재 시점의 직전과 이전 공격 시점의 차이를 기준으로 계산해야 한다. 즉, 초당 회복량 * (현재 시점 - 1 - 이전 공격 시점) + 추가 회복량 * ((현재 시점 - 1 - 이전 공격 시점) // (붕대 감기 시전 시간))이 된다.

4. 캐릭터의 체력은 최대 체력을 초과할 수 없다.

5. 캐릭터의 체력이 0이 되면 -1을 반환한다.

 

따라서 반복문 내에서 회복한 후의 체력 계산 -> 최대 체력 초과 여부 확인 -> 공격 받은 후의 체력 계산 -> 사망 여부 확인 순으로 동작하면 된다.

def solution(bandage, health, attacks):
    # 최대 체력 저장
    max_health = health
    
    # attacks에 대해 반복
    for i, (cur_time, damage) in enumerate(attacks):
        # 시작 시점이 아닌 경우 회복량 계산
        if i > 0:
            gap = cur_time - 1 - attacks[i - 1][0]
            health += bandage[1] * gap + bandage[2] * (gap // bandage[0])
            
        # 최대 체력 초과 여부
        if health > max_health:
            health = max_health
        
        # 공격 받은 후 결과 계산
        health -= damage
        
        # 캐릭터 사망 여부
        if health <= 0:
            return -1
    
    return health

 

 

참고 문서

https://school.programmers.co.kr/learn/courses/30/lessons/250137