프로그래머스 크레인 인형뽑기

1. 문제 링크

프로그래머스 크레인 인형뽑기 게임

2. 문제 조건

  • 게임 사용자는 크레인을 좌우로 움직여서 멈춘 위치에서 가장 위에 있는 인형을 집어 올릴 수 있습니다. 집어 올린 인형은 바구니에 쌓이게 되는 데, 이때 바구니의 가장 아래 칸부터 인형이 순서대로 쌓이게 됩니다.

  • 만약 같은 모양의 인형 두 개가 바구니에 연속해서 쌓이게 되면 두 인형은 터뜨려지면서 바구니에서 사라지게 됩니다. 위 상태에서 이어서 [5번] 위치에서 인형을 집어 바구니에 쌓으면 같은 모양 인형 두 개가 없어집니다.

  • 크레인 작동 시 인형이 집어지지 않는 경우는 없으나 만약 인형이 없는 곳에서 크레인을 작동시키는 경우에는 아무런 일도 일어나지 않습니다.

  • 제한 사항

  • board 배열은 2차원 배열로 크기는  이상  이하입니다.

    5 x 5

    30 x 30

  • board의 각 칸에는 0 이상 100 이하인 정수가 담겨있습니다.

    • 0은 빈 칸을 나타냅니다.
    • 1 ~ 100의 각 숫자는 각기 다른 인형의 모양을 의미하며 같은 숫자는 같은 모양의 인형을 나타냅니다.
  • moves 배열의 크기는 1 이상 1,000 이하입니다.

  • moves 배열 각 원소들의 값은 1 이상이며 board 배열의 가로 크기 이하인 자연수입니다.

3. 컴퓨팅 사고

  • 두개의 동일한 인형일 경우 바구니 remove
  • 빈곳일 경우 아무일도 일어나지 않는다. 즉, 크레인에서 뽑은 값은 인형 N*N에서 value 를 0 으로 초기화
  • 바구니 크기는 충분하다
  • board range (5 < board < 30)
  • moves range(1 < moves < 1000
  • board value range(1 < board value < 100)
  • stack의 empty조건과 인형맵에서 값이 있을 경우만 로직을 진행
  • 로직이 모두 진행되고나서 0으로 초기화 후 해당 로직을 빠져오는것이 가장 중요한 포인트였다.

Stack 자료구조를 사용한다.

이 크레인인형뽑기의 문제에서 가장 중요했던 부분은 Stack을 사용하여 바구니의 역할을 하게 해야한다. 그리고 그 바구니가 비어있는지의 조건을 무조건 체크하고 들어가고, 비어있으면서도 값이 있는 경우를 조건으로 처리해야한다. 그 이유는 한가지 조건만 만족시키면 문제의 조건과 stack의 조건을 만족시키지 못한다

그리고, 바구니에 들어져 있는 값이 현재 뽑은 인형과의 값을 비교하여 바구니의 값을 빼주면서 answer의 값을 +2 를 해준다. 그 이유는 바구니에 들어가 있는 값(+1)과 크레인이 뽑은 값(+1)이 동일한 인형이기 때문에 이 경우 answer에다가 값을 +2를 해주었다. 결국 바구니의 값과 크레인의 값이 같으니 2개의 인형이 remove되었다고 생각하면 된다.

인형을 뽑고나면 값을 0으로 초기화 시켜준다.

그리고 해당 로직이 다 실행되고 나면 크레인이 뽑은 인형의 값을 '0’으로 초기화 시켜준다. 그 이유는 '0’으로 초기화 시켜주지 않으면 다음로직시에도 해당 인형을 또 뽑을 수 있기 때문이다. 그리고 이때 해당 로직을 진행후 break;문을 사용하여 해당 로직을 빠져나온다. break를 해주지 않으면 다음 로직시에 뽑으려고 하지 않았던 인형과의 충돌이 생길 수 있다.

예) 1번 인형을 뽑고 3번을 뽑고 다시 1번으로 오는 경우

Input으로 들어오는 값들의 Init 값이 1부터시작하기 때문에 moves[i]-1;을 해주면서 0(Index)의 값으로 진행시키기 위함이다.

4. 소스 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <string>
#include <vector>
#include <stack>
#include <iostream>
using namespace std;

int solution(vector<vector<int>> board, vector<int> moves) {
int answer = 0;
stack<int> s;
for(int i=0; i<moves.size(); i++){
int moves_size = moves[i]-1;
for(int j=0; j<board.size(); j++){
// 인형이 있는 경우
if(board[j][moves_size] != 0){
if(!s.empty() && s.top() == board[j][moves_size]){
s.pop();
answer +=2;
}else {
s.push(board[j][moves_size]);
}
board[j][moves_size] = 0;
break;
}
}
}
return answer;
}