[BOJ] 4396번 지뢰찾기 - JAVA

최영환·2024년 8월 20일
0
post-thumbnail

💡 문제

💬 입출력 예시

📌 풀이(소스코드)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    static int N;
    static boolean isBoom = false;
    static final int[] dr = {-1, -1, -1, 0, 0, 1, 1, 1};
    static final int[] dc = {-1, 0, 1, -1, 1, -1, 0, 1};
    static char[][] mineBoard, playBoard, resultBoard;

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        N = Integer.parseInt(br.readLine());
        mineBoard = new char[N][N];
        playBoard = new char[N][N];
        resultBoard = new char[N][N];

        inputBoard(br, mineBoard);
        inputBoard(br, playBoard);
        initResultBoard();

        process();
        boom();

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < N; i++) {
            sb.append(resultBoard[i]).append("\n");
        }
        System.out.println(sb);
    }

    private static void inputBoard(BufferedReader br, char[][] playBoard) throws IOException {
        for (int i = 0; i < N; i++) {
            String input = br.readLine();
            for (int j = 0; j < N; j++) {
                playBoard[i][j] = input.charAt(j);
            }
        }
    }

    private static void initResultBoard() {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                resultBoard[i][j] = '0';
            }
        }
    }

    private static void process() {
        for (int r = 0; r < N; r++) {
            for (int c = 0; c < N; c++) {
                if (playBoard[r][c] == 'x') {
                    if (mineBoard[r][c] == '*') {
                        isBoom = true;
                        continue;
                    }
                    countMines(r, c);
                }

                if (playBoard[r][c] == '.') {
                    resultBoard[r][c] = playBoard[r][c];
                }
            }
        }
    }

    private static void countMines(int r, int c) {
        for (int d = 0; d < 8; d++) {
            int nr = r + dr[d];
            int nc = c + dc[d];

            if (nr < 0 || nc < 0 || nr >= N || nc >= N) {
                continue;
            }

            if (mineBoard[nr][nc] == '*') {
                resultBoard[r][c]++;
            }
        }
    }

    private static void boom() {
        if (isBoom) {
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    if (mineBoard[i][j] == '*') {
                        resultBoard[i][j] = '*';
                    }
                }
            }
        }
    }
}

📄 해설

접근

  • 출력문을 만드는 조건이 출력문 설명 부분에 있어서.. 문제를 읽자마자 이해하기 좀 난해했다 😑
  • 그래도 설명 부분을 찾았다면, 접근 자체는 쉽게 가능하다. 주어진 조건에 따라 구현하면 되는 간단한 문제이다.
  • 한가지 주의할 점은 작성자의 실수이긴한데, 지뢰를 밟으면 모든 지뢰를 표시해야한다. 라는 부분이다. 지뢰찾기 하다가 지뢰를 클릭했을 때의 상태를 만들라는 것. 이를 위해 isBoom 이라는 플래그 변수를 사용하였다.
    • 혹시라도 15% 부근에서 실패하는 사람이 있다면, 이 과정을 거쳤는지 확인해보길 바란다. 😅

과정

  • 총 세 개의 2차원 char 배열을 사용했고, 각각 지뢰의 위치 정보, 플레이 결과 정보, 결과 정보 를 담는 배열들이다.
  • 플레이 결과 정보를 담는 배열인 playBoard 를 순회하면서 해당 위치가 열려있는 위치인지를 확인한다. if (playBoard[r][c] == 'x)
    • 열려있는 위치라면 지뢰인지를 확인하고, 지뢰라면 isBoom = true 로 바꾸고 반복문으로 복귀한다.
    • 지뢰가 아닌 경우, 8방 탐색을 통해 근처에 지뢰가 몇개인지를 세고, 결과를 resultBoard 에 반영한다.
  • 열려있지 않은 경우, resultBoard 의 해당 위치에 . 을 저장한다.
  • playBoard 에 대한 순회가 끝나면, isBoom 이 true 인지 false 인지 확인한다. 이때, isBoom 이 true 인 경우, 지뢰를 누른 것이므로 모든 지뢰의 위치를 resultBoard 에 반영한다.
profile
조금 느릴게요~

0개의 댓글