프로그래머스 PCCP 붕대감기

2023. 12. 7. 17:25기타

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

 

프로그래머스

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

programmers.co.kr

 

문제설명

 

수도코드

조건

시전 시간 * 초당 회복량 = 체력회복량
(시전 시간) 연속으로 붕대를 감으면 추가 회복량 만큼 체력회복
최대체력은 health보다 올라갈 없다.
공격당하면 체력회복이 불가능하고 기술이 취소되며, 연속시간 0으로 초기화

bandage는 [시전 시간, 초당 회복량, 추가 회복량]
health는 최대체력
attacks[i] = [공격 시간, 피해량] 이고 공격시간을 기준으로 오름차순 정렬 되어있다.

로직구성

1.붕대는 그냥 0초부터 감고있는다고 가정(추가회복 스택을 쌓기 위함)
2.attacks[i][0] 초에 attacks[i][1] 데미지가 들어옴 (attacks[i][0]만큼 붕대 스택 쌓여있음)
3.health = health - attacks[i][1] 된다.
4.공격당한 턴에는 회복이 불가능하며 힐스택이 초기화된다.
5. 버텨야 하는 시간은 attacks[attacks.length-1][0] 만큼만 버티면 된다.
6.attacks[attacks.length-1][0] 시간동안 attacks[i][1]들의 총합만큼 데미지가 들어오며, (attacks[attacks.length-1][0] * 초당회복) + @(추가회복량) 만큼 체력을채운다.

결론 

1.플탐만큼 반복문을 돌면서, 반복마다 힐스택을 쌓으며 현재 반복횟수(시간) attacks[공격탐][0] 같다면, attacks[공격탐][1]만큼 체력에서 빼준다.
동시에 힐스택을 초기화하고 공격탐을 ++해준다
2. 공격턴이 아니고, 최대체력보다 낮을 시에는 매초마다 초당회복량만큼 체력에 더해준다 (회복량이 최대체력을 넘어간다면 최대체력으로 만들어준다.)
3. 힐스택이 시전시간과 같아지면 추가회복을 하고 힐스택을 초기화해준다.
3. 체력회복 최대체력이상으로 회복하는지 체크해야한다
 

 

풀이코드

 

function solution(bandage, health, attacks) {
  [시전시간, 초당회복, 추가회복] = bandage;
  const 최대체력 = health;
  let 힐스택 = 0;
  let 플탐 = attacks[attacks.length - 1][0];
  let 공격탐 = 0;
  let 체력 = health;

  for (let 시간 = 0; 시간 <= 플탐; 시간++) {
    if (체력 < 1) {
      // 체력이 0이 될 경우 게임을 멈춘다.
      break;
    }
    if (시간 === attacks[공격탐][0]) {
      //공격당한 턴
      체력 -= attacks[공격탐][1];
      힐스택 = 0;
      공격탐++;
    } else if (시간 !== attacks[공격탐][0]) {
      //공격 당하지 않은 턴
      힐스택++;
      if (체력 < 최대체력) {
        // 현재체력이 안깎여 있다면 회복하지않고, 깎였다면 붕대를 감는다.
        if (체력 + 초당회복 >= 최대체력) {
          // 회복 될 양이 최대체력보다 크다면
          체력 = 최대체력; // 체력을 다 채워준다.
        } else {
          체력 += 초당회복; // 아니라면 초당회복량만큼 체력에 더해준다.
        }
      }
    }
    if (힐스택 === 시전시간) {
      // 연속성공했을 시,
      힐스택 = 0; //힐스택 초기화
      if (체력 + 추가회복 >= 최대체력) {
        // 회복 될 양이 최대체력보다 크다면
        체력 = 최대체력; // 체력을 다 채워준다.
      } else {
        // 아니라면 추가회복량만큼 체력에 더해준다.
        체력 += 추가회복;
      }
    }
  }
  return 체력 < 1 ? -1 : 체력;
}

 

 

시행착오

테스트케이스 점수가

26 > 34 > 60 > 100 으로 한번에 통과한 문제가 아닌만큼 놓친부분이 많았다.

 

첫번째 힐스택을 초기화 해주지 않았다.

처음 코드는 if(힐스택 === 시전시간) 조건에 부합하면, 추가 회복을 시켜줬다.

여기서 힐스택을 초기화 해주지 않는다면 힐스택은 시전시간보다 커질것이고 처음에 추가회복 이후에는 더이상 추가회복이 되지않는다.

기본 테스트케이스에는 연속해서 추가회복을 할 만큼의 힐스택을 쌓을정도의 테스트케이스가 없었어서 통과가 됐지만 다른 테스트케이스에는 현재 시간과 다음 공격턴 가지의 턴동안 추가회복을 연속으로 사용할 경우가 있는 케이스가 있었나보다.

이 케이스를 커버하기위해 추가회복 시, 힐스택을 초기화해줬다.

 

 

두번째 최대회복량을 고려하지 못했다.

회복 시, 최대체력이상으로는 회복을 못한다는 조건이 있었다.

인지하고있었고 해당케이스 커버를 위해 if(체력 < 현재체력) 으로 조건을 걸어서 체력이 깎여있을때에만 회복을 하도록 코드를 짰다.

하지만 회복량이 큰 케이스에서는 깎인 체력보다 회복량이 컸고, 그 경우에는 최대체력을 상회하면서 에러가 발생했다.

이 케이스를 커버하기위해 if(체력 < 현재체력) 조건 안에 내부 조건으로 if(체력 + 초당회복 또는 추가회복 >  현재체력) 조건을 걸어서 이 조건에 만족한다면 체력 = 최대체력으로 설정해줬다.

이로써 회복량이 최대체력을 넘을 시에는 체력을 모두 회복해주는 식으로 케이스를 커버했다.

 

이러한 케이스들을 모두 커버한 결과

 

네번의 코드수정으로 통과!

아직 1번 문제에서도 40분이상 사용하는 걸 보니 막막하다 ..

알고리즘 천재로 태어나고 싶다 흨흨

풀다보면 늘겠지 ..