본문 바로가기

백준

백준 4396 지뢰 찾기 (JAVA)

문제

https://www.acmicpc.net/problem/4396

 

4396번: 지뢰 찾기

지뢰찾기는 n × n 격자 위에서 이루어진다. m개의 지뢰가 각각 서로 다른 격자 위에 숨겨져 있다. 플레이어는 격자판의 어느 지점을 건드리기를 계속한다. 지뢰가 있는 지점을 건드리면 플레이어

www.acmicpc.net

코드

package com.company;

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

class Main {

    static char[][] map;
    static char[][] boom;
    static int[] dir_x = {-1, -1, -1, 0, 1, 1, 1, 0};
    static int[] dir_y = {-1, 0, 1, 1, 1, 0, -1, -1};
    static boolean flag = false;
    static int n;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        n = Integer.parseInt(br.readLine());
        map = new char[n][n];
        boom = new char[n][n];

        //지뢰 매설 지도 -> boom
        for (int i = 0; i < n; i++) {
            String str = br.readLine();
            for (int j = 0; j < n; j++) {
                boom[i][j] = str.charAt(j);
            }
        }

        //열었는 좌표 저장 -> map
        for (int i = 0; i < n; i++) {
            String str = br.readLine();
            for (int j = 0; j < n; j++) {
                map[i][j] = str.charAt(j);
            }
        }

        //정상적인 프로세스
        process();

        checkBoom();

        for (char[] chars : map) {
            for (char aChar : chars) {
                sb.append(aChar);
            }
            sb.append("\\n");
        }

        System.out.println(sb.toString());
    }

    private static void checkBoom() {
        if(flag) {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    if(boom[i][j] == '*')
                        map[i][j]= '*';
                }
            }
        }
    }

    private static void process() {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if(map[i][j] == 'x'){
                    if(boom[i][j] == '*')
                        flag = true;
                    else {
                        countBoom(i, j);
                    }
                }
                else
                    map[i][j] = '.';
            }
        }
    }

    private static void countBoom(int i, int j) {
        int count = 0;

        for (int k = 0; k < 8; k++) {
            int x = i + dir_x[k];
            int y = j + dir_y[k];
            if(0 <= x && x <= n-1 && 0 <= y && y <= n-1){
                if(boom[x][y] == '*')
                    count++;
            }
        }
        map[i][j] = (char) (count + '0');
    }

}

풀이

처음 내가 생각해내었는 풀이 방식은 지뢰가 터지지 않는 경우에는 올바르게 동작하였으나 지뢰가 터지는 경우에 있어서는 문제가 발생하였다. 내가 생각한 방식으로는 이미 지나온 공간에 대해서는 검사를 하거나 지뢰가 있다는 것을 표시하는 것이 불가 하였다. 그렇기에 다른 사람의 풀이를 보았고 결국 다음과 같이 풀었다.

필요한 저장공간은 지뢰가 매설 되어 있는 지도와 게임을 플레이한 기록을 저장하는 지도이고 다음과 같이 진행한다. 만약 열어보았는 좌표이면서 지뢰가 매설되어있지 않았다면 주변에 위치한 지뢰의 수를 확인하고 원래 게임을 플레이한 기록을 저장한 지도에 표시를 해둔다. 이때 만약 지뢰를 터트렸다면 따로 flag라는 변수를 true로 해줌으로 기록해둔다. 그리고 전체 좌표에 대해서 작업을 마친다면 이후 flag라는 변수를 통해 만약 지뢰가 터졌었다면 지뢰가 매설되어있는 지도를 통해 게임을 플레이한 지도의 위치에 표시를 해둔다.

'백준' 카테고리의 다른 글

백준 12933 오리 (JAVA)  (0) 2022.07.14
백준 1913 달팽이 (JAVA)  (0) 2022.07.11
백준 2578 빙고 (JAVA)  (0) 2022.07.07
백준 20546 🐜기적의 매매법🐜 (JAVA)  (0) 2022.07.05
백준 21918 전구 (JAVA)  (0) 2022.07.05