본문 바로가기

프로그래머스(Java)/Level 2

[프로그래머스] [1차] 프렌즈4블록

728x90

코드 힌트:

  1. 2x2 블록 찾기:
    • 맵을 탐색하면서 2x2 크기의 동일한 블록을 찾습니다.
    • 만약 발견되면, 해당 블록의 인덱스를 저장합니다.
  2. 블록 제거:
    • 저장된 블록의 인덱스를 이용해 해당 블록들을 '0'으로 설정하여 제거합니다.
    • 이 과정에서 블록이 떨어지게 됩니다.
  3. 블록 내리기:
    • 블록이 제거된 후, 위에 있는 블록들이 아래로 떨어지도록 맵을 업데이트합니다.
  4. 반복:
    • 위 과정을 블록이 더 이상 제거되지 않을 때까지 반복합니다.
    • 게임이 끝나면 제거된 블록의 총 개수를 반환합니다.

 

 


정답은 더보기 클릭

더보기
import java.util.*;

class Solution {
    // 2x2 블록을 찾아서 제거하고, 블록이 제거된 후 위에 있는 블록을 아래로 내리는 게임 로직 구현
    public int solution(int m, int n, String[] board) {
        int result = 0; // 제거된 블록의 수를 세기 위한 변수
        // 게임 맵을 초기화
        char[][] map = initArr(m, n, board);
        
        // 게임 루프 시작
        boolean isRunning = true;
        while (isRunning) {
            isRunning = false;
            Queue<String> q = new LinkedList<>(); // 제거할 블록의 인덱스를 저장하는 큐
            
            // 맵을 순회하면서 2x2 블록을 찾기
            for (int i = 0; i < m-1; i++) {
                for (int j = 0; j < n-1; j++) {
                    // 2x2 블록이 있는지 확인
                    if (map[i][j] != '0' && map[i][j] == map[i][j+1]
                       && map[i][j] == map[i+1][j]
                       && map[i+1][j] == map[i+1][j+1]) {
                        isRunning = true; // 제거할 블록이 있으므로 게임을 계속 진행
                        
                        // 큐에 블록의 인덱스를 저장, 중복을 피하기 위해 이미 저장된 인덱스는 무시
                        if (!q.contains(i+" "+j))
                            q.add(i+" "+j);
                        if (!q.contains(i+" "+(j+1)))
                            q.add(i+" "+(j+1));
                        if (!q.contains((i+1)+" "+j))
                            q.add((i+1)+" "+j);
                        if (!q.contains((i+1)+" "+(j+1)))
                            q.add((i+1)+" "+(j+1));
                    }
                }
            }

            // 제거된 블록의 수를 더함
            result += q.size();

            // 큐에 있는 블록 인덱스들을 제거
            while (!q.isEmpty()) {
                String[] tmpArr = q.poll().split(" ");
                map[Integer.parseInt(tmpArr[0])][Integer.parseInt(tmpArr[1])] = '0'; // 블록을 '0'으로 설정해 제거
            }
            
            // 블록들이 제거된 후 위에 있는 블록을 아래로 내리기
            blockMove(m, n, map);
        }
        
        return result; // 제거된 총 블록 수 반환
    }
    
    // 현재 맵의 상태를 출력하는 디버그용 메소드
    public void showArray(char[][] map) {
        for (char[] cArr : map) {
            System.out.println(Arrays.toString(cArr));
        }
    }
    
    // 블록들이 제거된 후 위에 있는 블록을 아래로 내리는 메소드
    public void blockMove(int m, int n, char[][] map) {
        for (int i = m-2; i >= 0; i--) { // 아래에서 위로 스캔
            for (int j = n-1; j >= 0; j--) { // 오른쪽에서 왼쪽으로 스캔
                int ni = i;
                // 블록이 아래로 이동할 수 있는지 확인
                while (m-1 > ni && map[ni+1][j] == '0') {
                    map[ni+1][j] = map[ni][j]; // 아래로 블록 이동
                    map[ni][j] = '0'; // 원래 위치를 '0'으로 설정
                    ni++;
                }
            }
        }
    }
    
    // 게임 보드 초기화 메소드
    public char[][] initArr(int m, int n, String[] board) {
        char[][] arr = new char[m][n]; // m x n 크기의 배열 생성
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                arr[i][j] = board[i].charAt(j); // 주어진 문자열 배열을 캐릭터 배열로 변환
            }
        }
        return arr;
    }
}
728x90