본문 바로가기
알고리즘

[Swift 알고리즘] 백준 4396 지뢰찾기

by 마라민초닭발로제 2023. 6. 11.

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

 

4396번: 지뢰 찾기

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

www.acmicpc.net

 

 

 

해결 방법 : 

[1 -1]    [1 0]    [1 1]

[0 -1]   [0 0]    [0 1]

[-1 -1]  [-1 0]   [-1 1]

의 따로 배열을 만들고 생각해서 풀었습니다. 이 배열을 rcVal이라고 가정합니다.

 

1. 우리가 궁금한 것은 지뢰근처에 숫자를 표기하는 것 입니다.

       if mine[i][j] == "*"

2. 그리고 궁금한 것은 지뢰에서 상화좌우 및 대각선까지 값을 넣을 수 있는지 아닌지가 궁금합니다. 이것을 우리는 rcVal로 해결할 것 입니다. rcVal에서 현재 탐색하는 i와(row) j의(col) ind에 대해서 생각을 해주면 됩니다.

 - 예를들어 row값이 0이라면 [-1, 1], [-1, 0], [-1, -1]의 ind는 탐색하지 못합니다. 

 - 또한 row값이 n - 1이라면 [n, 1] [n, 0], [n, -1]의 ind는 탐색하지 못합니다.

 - 이는 column또한 마찬가지 입니다.

let tempRC = [k[0] + i, k[1] + j]
if tempRC[0] < 0 || tempRC[0] >= inputN || tempRC[1] < 0 || tempRC[1] >= inputN {
    continue
}

 

3. 만약 지뢰를 밟게 된다면 flag값을 통해, 지뢰탐색이 끝난 후 다시 재탐색 합니다.

if flag == 1 {
    for i in 0..<inputN {
        for j in 0..<inputN {
            if mine[i][j] == "*" {
                user[i][j] = "*"
            }
        }
    }
}

 

 

 

 

전체 코드입니다.

import Foundation


func sol3() {
    let inputN = Int(readLine()!)!
    var mine:[[String]] = []
    var user:[[String]] = []
    for _ in 0..<inputN {
        let temp = readLine()!.map{String($0)}
        mine.append(temp)
    }
    for _ in 0..<inputN {
        let temp = readLine()!.map{String($0)}
        user.append(temp)
    }
    user = user.map{ arr in
        arr.map { val in
            if val == "x" {
                return "0"
            }
            return val
        }
    }
    let rcVal = [[-1, 0],[-1, 1], [-1, -1], [0, 1], [0, -1], [1, 1], [1, -1], [1, 0]]
    var flag = 0
    for i in 0..<inputN {
        for j in 0..<inputN {
            if mine[i][j] == "*" {
                if user[i][j] != "." {
                    flag = 1
                }
                for k in rcVal {
                    let tempRC = [k[0] + i, k[1] + j]
                    if tempRC[0] < 0 || tempRC[0] >= inputN || tempRC[1] < 0 || tempRC[1] >= inputN {
                        continue
                    }else {
                        if user[tempRC[0]][tempRC[1]] != "." {
                            user[tempRC[0]][tempRC[1]] = String(Int(user[tempRC[0]][tempRC[1]])! + 1)
                        }
                    }
                }
            }
        }
    }
    if flag == 1 {
        for i in 0..<inputN {
            for j in 0..<inputN {
                if mine[i][j] == "*" {
                    user[i][j] = "*"
                }
            }
        }
    }
    user.map{print($0.joined())}
}
sol3()

 

 

후기 : 이런 류의 문제를 풀 때 나는 모든 경우의수를 구했다.

 

하지만... 이렇게 구하지 않아도 된다는 사실을 알고 한층 성장하는 계기가 되었습니다.