프로그래머스-PCCP 기출문제 1번(붕대 감기)

Flash·2023년 11월 24일
0

Programmers-Algorithm

목록 보기
50/52
post-thumbnail

구현

프로그래머스에서 코딩 테스트를 준비하던 중 PCCP 기출문제라는 문제집이 추가되었길래 풀어보았다. 아직 올라온 지 얼마 되지 않아 관련 글이 많이 없길래 내 풀이를 공유해본다.
정확한 문제 제목은 없이 번호만 써져있지만 굳이 이름을 붙이자면 붕대 감기 라는 이름을 붙일 수 있을 것 같다. 문제 링크는 아래와 같다.
https://school.programmers.co.kr/learn/courses/30/lessons/250137


그리디

그냥 게임이 진행되는 시간동안 계속해서 매초마다 필요한 작업들을 경우의 수에 맞춰 진행하면 된다.
0초에는 아무런 일이 일어나지 않기 때문에 1초부터 시작해서 게임이 종료될 때까지 반복문을 돌리는 방식으로 풀었다.
반복문은 조기에 종료될 수도 있고 모든 공격을 마칠 때까지 돌 수도 있다.

현재 체력 검증

반복문이 조기에 종료되는 경우부터 살펴보자. 한 턴(1초)을 돌은 이후에 현재 체력이 0 이하로 떨어지게 되면 모든 공격을 살펴볼 필요 없이 -1 을 반환하며 게임을 종료한다. 매 턴마다 갱신하게 될 현재 체력을 curHealth라는 이름의 변수로 초기화해서 반복문 한 번을 돌 때마다 0 이하인지 점검해주자.
코드의 일부분만 살펴보자면 다음과 같다.

for (int i = 1; i <= endTime; i++) {
            
    /* 공격 혹은 체력 회복을 진행... */

    if (curHealth <= 0) { // 이번 턴을 마치고 체력이 바닥났다면 종료
        return -1;
    }
}

공격 정보 초기화

int[][] attacks 에 담겨있는 공격 정보를 Map 을 이용해 초기화했다. 매 초마다 공격이 있는지 없는지 확인하기 위해 공격시각을 key로, 피해량을 value로 저장해뒀다. 그리고 매 초마다 공격 여부를 확인했다.
코드의 일부분만 살펴보자면 다음과 같다.

for (int[] attack : attacks) {
	attackInfo.put(attack[0], attack[1]);
	endTime = attack[0];
}

for (int i = 1; i <= endTime; i++) {
	if (attackInfo.containsKey(i)) { // 공격이 있다면
		// 피해량 반영...
	} else { // 공격이 없다면
		// 체력 회복 반영...
	}

	if (curHealth <= 0) { // 이번 턴을 마치고 체력이 바닥났다면 종료
		return -1;
	}
}

현재 체력 갱신과 체력 회복 연속 성공 시간 갱신

이제 공격이 있을 때 피해량 반영과 공격이 없을 때 체력 회복을 하는 부분만 구현을 하면 된다.

공격 받을 경우

공격을 받는 경우부터 살펴보자. 앞서 Map에 초기화해둔 해당 공격의 피해량만큼을 현재 체력에서 빼주면 된다. 이때 함께 해주어야 할 추가적인 작업이 있다. 체력 회복 연속 성공 시간을 0 으로 갱신해줘야 한다.
이를 코드로 옮기면 다음과 같다.

curHealth -= attackInfo.get(i);
successiveTime = 0;

공격이 없을 때

공격이 없을 때는 체력을 회복하는 작업을 진행해주면 된다.
이때 해주어야 할 작업을 세분화하면 총 4가지다.

  • 현재 체력에 초당 회복량 반영
  • 체력 회복 연속 성공 시간 1 증가
  • 체력 회복 연속 성공 시간이 기술 시전 시간과 동일해졌다면 추가 회복량을 현재 체력에 반영
  • 위의 과정들을 다 마친 후에 현재 체력이 최대 체력보다 커진 경우에 최대 체력으로 갱신

위 4가지만을 코드로 보면 다음과 같다.

curHealth += bandage[1]; // 1번 작업
successiveTime++; // 2번 작업

if (successiveTime == bandage[0]) { // 3번 작업
	curHealth += bandage[2];
	successiveTime = 0;
}
if (curHealth > health) { // 4번 작업
	curHealth = health;
}

전체 코드

위의 모든 작업들을 하나로 합친 내가 제출한 전체 코드는 다음과 같다.

import java.util.HashMap;
import java.util.Map;

public class PCCP1번 {

    static Map<Integer, Integer> attackInfo = new HashMap<>();
    static int endTime = 0;
    static int curHealth = 0;
    static int successiveTime = 0;

    public int solution(int[] bandage, int health, int[][] attacks) {
        curHealth = health;
        for (int[] attack : attacks) {
            attackInfo.put(attack[0], attack[1]);
            endTime = attack[0];
        }

        /* 1초부터 마지막 공격 시각까지 체력 정보 초기화 */
        for (int i = 1; i <= endTime; i++) {
            if (attackInfo.containsKey(i)) { // 공격이 있다면
                curHealth -= attackInfo.get(i);
                successiveTime = 0;
            } else { // 공격이 없다면
                curHealth += bandage[1];
                successiveTime++;

                if (successiveTime == bandage[0]) {
                    curHealth += bandage[2];
                    successiveTime = 0;
                }
                if (curHealth > health) {
                    curHealth = health;
                }
            }

            if (curHealth <= 0) { // 이번 턴을 마치고 체력이 바닥났다면 종료
                return -1;
            }
        }

        return curHealth;
    }
}
profile
개발 빼고 다 하는 개발자

0개의 댓글