본문 바로가기
코딩테스트

백준 - 늑대와 양 - 16956 - swift

by vapor3965 2021. 8. 25.

목차

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

     

    16956번: 늑대와 양

    크기가 R×C인 목장이 있고, 목장은 1×1 크기의 칸으로 나누어져 있다. 각각의 칸에는 비어있거나, 양 또는 늑대가 있다. 양은 이동하지 않고 위치를 지키고 있고, 늑대는 인접한 칸을 자유롭게

    www.acmicpc.net

     

     

    실버 4의 낮은 난이도지만, 재밌는 문제였다.

     

    문제 유형은 구현에 가깝다. 또는 bfs로도 풀 수 있긴 하다.

    즉 bfs를 몰라도 풀 수 있는 문제다. 

    사실 나도 문제를 보자마자 bfs가 딱 떠올랐다. 

    대체로 bfs나 dfs가 들어가면 최소 실버1~2의 난이도를 갖는데, 의아했다. 왜 실버 4일까? 

     

    처음에는 늑대를 기준으로 bfs를 돌리면서 양을 만나는...이런 생각을 하다가,

    양을 기준으로 잡아서, 양의 주변에 . 가 있다면 바로 울타리르 심는 걸로 하고, 더 이상 탐색하지 않고, 

    양이 있다면 계속 탐색하고, 늑대가 있다면 안전하지 않다는 걸로 구현했다.

     

    풀긴 풀었지만, bfs가 들어가면 코드가 더 길어지는게 어쩔 수 없는데, 다른 분들의 코드들이 대체로 짧은 걸 보고, 

    다시 생각했다. 

     

    오!  사실 이 문제는 울타리를 최소로 심는게 아니다. 그냥 울타리를 어디든 지어도 늑대가 접근하지 못하면 성공이다. 

     

    즉, 그냥 아예 처음부터 . 인 곳은 울타리를 심어버린다. 

    그리고 ?

    그냥 2차원배열을 돌면서, 늑대인경우에, 좌우 위아래 양이 있는지만 판별하면 된다. 

     

    이미 양과 늑대를 제외한 곳은 이미 울타리로 다 쳐져있기때문에, 좌우위아래로 양이 존재한다면 이는 어떤식으로든 늑대가 양을 찾을 수 밖에 없다.

     

    ㅎㅎ 재밌는 문제다.

     

     

    let inp = readLine()!.split(separator: " " ).map{Int(String($0))!}
    let row = inp[0], col = inp[1]
    var arr = [[String]]()
    for _ in 0..<row {
        var l = readLine()!.map{String($0)}
        for j in 0..<col {
            if l[j] == "." {
                l[j] = "D"
            }
        }
        arr.append(l)
    }
    let dir = [(0,1),(0,-1),(1,0),(-1,0)]
    var isSafe = true
    
    for i in 0..<row {
        for j in 0..<col {
            if arr[i][j] != "W" { continue }
            for k in 0..<4 {
                let n = (i+dir[k].0, j+dir[k].1)
                if n.0>=row||n.1>=col||n.0<0||n.1<0{continue}
                if arr[n.0][n.1] == "S" {
                    isSafe = false
                    break
                }
            }
        }
    }
    
    if isSafe {
        print(1)
        arr.forEach {
            print($0.joined())
        }
    } else {
        print(0)
    }

    댓글