문제 보기

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

문제

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

붕대 감기는 t초 동안 붕대를 감으면서 1초마다 x만큼의 체력을 회복합니다. t초 연속으로 붕대를 감는 데 성공한다면 y만큼의 체력을 추가로 회복합니다. 게임 캐릭터에는 최대 체력이 존재해 현재 체력이 최대 체력보다 커지는 것은 불가능합니다.

기술을 쓰는 도중 몬스터에게 공격을 당하면 기술이 취소되고, 공격을 당하는 순간에는 체력을 회복할 수 없습니다. 몬스터에게 공격당해 기술이 취소당하거나 기술이 끝나면 그 즉시 붕대 감기를 다시 사용하며, 연속 성공 시간이 0으로 초기화됩니다.

몬스터의 공격을 받으면 정해진 피해량만큼 현재 체력이 줄어듭니다. 이때, 현재 체력이 0 이하가 되면 캐릭터가 죽으며 더 이상 체력을 회복할 수 없습니다.

당신은 붕대감기 기술의 정보, 캐릭터가 가진 최대 체력과 몬스터의 공격 패턴이 주어질 때 캐릭터가 끝까지 생존할 수 있는지 궁금합니다.

붕대 감기 기술의 시전 시간, 1초당 회복량, 추가 회복량을 담은 1차원 정수 배열 bandage와 최대 체력을 의미하는 정수 health, 몬스터의 공격 시간과 피해량을 담은 2차원 정수 배열 attacks가 매개변수로 주어집니다. 모든 공격이 끝난 직후 남은 체력을 return 하도록 solution 함수를 완성해 주세요. 만약 몬스터의 공격을 받고 캐릭터의 체력이 0 이하가 되어 죽는다면 -1을 return 해주세요.

 

 

제한사항
  • bandage는 [시전 시간, 초당 회복량, 추가 회복량] 형태의 길이가 3인 정수 배열입니다.
    • 1 ≤ 시전 시간 = t ≤ 50
    • 1 ≤ 초당 회복량 = x ≤ 100
    • 1 ≤ 추가 회복량 = y ≤ 100
  • 1 ≤ health ≤ 1,000
  • 1 ≤ attacks의 길이 ≤ 100
    • attacks[i]는 [공격 시간, 피해량] 형태의 길이가 2인 정수 배열입니다.
    • attacks는 공격 시간을 기준으로 오름차순 정렬된 상태입니다.
    • attacks의 공격 시간은 모두 다릅니다.
    • 1 ≤ 공격 시간 ≤ 1,000
    • 1 ≤ 피해량 ≤ 100

 

 

풀이방법

실제 게임 타임라인이라고 생각하고 시뮬레이션으로 풀면 될 것 같다.

그러기 위해 마지막 공격 시간이 언제인지부터 찾았고,

이번 타임에 공격이 올지 오지 않을지 판단하기 위해 HashMap을 사용하였다.

 

1초부터 마지막 공격 시간까지 돌려보며 시뮬레이션을 진행해보자.

 

자세한 내용은 전체 코드에 주석을 하나하나 달아놓았으니 참고.

 

 

전체 코드 & 주석
import java.util.HashMap;

class Solution {
    public int solution(int[] bandage, int health, int[][] attacks) {
int answer = 0;

        int lastTime = attacks[attacks.length - 1][0]; // 몬스터의 마지막 공격 시간
        HashMap<Integer, Integer> attacksMap = new HashMap<>(); // attacks 배열을 hashMap으로 만들어 서치 시간을 줄일 것
        for (int i = 0; i < attacks.length; i++) {
            attacksMap.put(attacks[i][0], attacks[i][1]); // 정보를 옮겨 담는다.
        }
        int continuity = 0; // 몇 초 연속 회복인지 기록
        int maxHealth = health; // 최대 체력
        int currentHealth = health; // 현재 체력

        for(int i = 1; i <= lastTime; i++) { // 1초부터 몬스터의 마지막 공격 까지
            if(attacksMap.containsKey(i)) { // 해시 맵에서 이번 초에 해당하는 key가 있는지 찾는다.
                currentHealth -= attacksMap.get(i); // 이번 초의 데미지만큼 현재 체력에서 마이너스
                continuity = 0; // 연속 성공 0으로 초기화
                if(currentHealth <= 0) { // 죽었나요?
                    return -1; // -1 리턴
                }
            } else { // 이번 초에 공격이 오지 않을 경우
                continuity++; // 연속 성공 ++
                currentHealth += bandage[1]; // 초당 회복량 +
                if(continuity >= bandage[0]) { // 만약 연속 성공이 시전 시간에 도달하였을 경우
                    currentHealth += bandage[2]; // 현재 체력에 추가 회복량 +
                    continuity = 0; // 연속 성공 0으로 초기화
                }
                if(currentHealth > maxHealth) // 만약 현재 체력이 최대 체력보다 높아졌다면?
                    currentHealth = maxHealth; // 최대 체력으로 맞춰준다.
            }
        }

        answer = currentHealth; // 여기까지 왔다면 죽지 않은 것이기 때문에 답은 남은 체력
        return answer;
    }
}

 

 

풀이 GitHub 링크

https://github.com/MetroDefro/CodingTest_AutoSave/tree/main/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/1/250137.%E2%80%85%EF%BC%BBPCCP%E2%80%85%EA%B8%B0%EC%B6%9C%EB%AC%B8%EC%A0%9C%EF%BC%BD%E2%80%851%EB%B2%88%E2%80%85%EF%BC%8F%E2%80%85%EB%B6%95%EB%8C%80%E2%80%85%EA%B0%90%EA%B8%B0

 

CodingTest_AutoSave/프로그래머스/1/250137. [PCCP 기출문제] 1번 / 붕대 감기 at main · MetroDefr

모든 코딩 테스트 자동 저장. Contribute to MetroDefro/CodingTest_AutoSave development by creating an account on GitHub.

github.com

 

+ Recent posts