Study/Algorithm

프로그래머스 / 크레인 인형뽑기 게임(Java)

개발개발개발 2020. 9. 24. 15:55

문제 설명

게임 개발자인 크레인 인형 뽑기 기계를 모바일 게임으로 만들려고 합니다.
죠르디는 게임의 재미를 높이기 위해 화면 구성과 규칙을 다음과 같이 게임 로직에 반영하려고 합니다.

게임 화면은 1 x 1 크기의 칸들로 이루어진 N x N 크기의 정사각 격자이며 위쪽에는 크레인이 있고 오른쪽에는 바구니가 있습니다. (위 그림은 5 x 5 크기의 예시입니다). 각 격자 칸에는 다양한 인형이 들어 있으며 인형이 없는 칸은 빈칸입니다. 모든 인형은 1 x 1 크기의 격자 한 칸을 차지하며 격자의 가장 아래 칸부터 차곡차곡 쌓여 있습니다. 게임 사용자는 크레인을 좌우로 움직여서 멈춘 위치에서 가장 위에 있는 인형을 집어 올릴 수 있습니다. 집어 올린 인형은 바구니에 쌓이게 되는 데, 이때 바구니의 가장 아래 칸부터 인형이 순서대로 쌓이게 됩니다. 다음 그림은 [1번, 5번, 3번] 위치에서 순서대로 인형을 집어 올려 바구니에 담은 모습입니다.

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

입출력 예

board moves result
[[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]] [1,5,3,5,1,2,1,4] 4

※이 문제는 2019 카카오 개발자 겨울 인턴십에 나온 문제이다.

 

조건 1 : moves 배열에 적힌 수에 따라 인형을 뽑아 따로 쌓는다.

조건 2: 같은 인형(숫자)이 2개 겹칠 시 그 인형은 2개 모두 사라진다.

 

 

내가 생각한 해결 방법

1. 해당하는 위치에 있는 숫자를 스택에 넣는다.

2. 다음 숫자를 넣기 전 마지막 수와 비교하여 다를 시, 스택에 그냥 추가하고

같을 시 맨 마지막 값을 삭제하고 answer를 2 증가시킨 후 바로 다음으로 넘어간다.

import java.util.Stack;

public class Main {
	public static int solution(int[][] board, int[] moves) {
		int answer = 0; 
		Stack<Integer> st = new Stack<>();
		
		st.add(0); //스택에 0을 넣은 이유는 어차피 0과 일치하는 수가 없기때문에 초기 값 설정
		
		
		int size = board[0].length;
		
		for(int i=0; i<moves.length; i++) {
			int move = moves[i]; //뽑을 위치
			
			for(int j=0; j<size; j++) {
				int brd = board[j][move-1]; //뽑을 위치에 있는 인형 값
				
				if(brd != 0) {
					int tmp = st.lastElement(); //마지막 값을 꺼내어 비교한다.
					if(tmp != brd) {
						st.add(brd); //값이 다르다면 그냥 새로운 인형을 스택에 더한다.
					}else {
						st.pop(); //값이 다르다면 마지막 값을 삭제하고 새로운 값도 넘기지 않는다.
						answer += 2; //그리고 없어졌다는 가정하에 +2
					}
					
					board[j][move-1] = 0; //꺼낸 인형자리에는 0을 채워 넣는다.
					break;
				}
			}
		}


		return answer;
	}

 

 

어떠한 특별한 알고리즘을 사용하기 보다는 논리적인 생각을 하는게 중요한 문제라고 생각한다.

나는 시간복잡도가 O(n^2) 인데 이것보다 더 낮출 수 있는 방법을 잘 모르겠다