๋ฐฑ์ค€ - ์น˜์ฆˆ(Swift)

2022. 11. 22. 16:26ใ†Algorithm

๋ฐฑ์ค€ - ์น˜์ฆˆ(Swift)

 

 

 ๋ฌธ์ œ ์„ค๋ช…

 

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

 

2636๋ฒˆ: ์น˜์ฆˆ

์•„๋ž˜ <๊ทธ๋ฆผ 1>๊ณผ ๊ฐ™์ด ์ •์‚ฌ๊ฐํ˜• ์นธ๋“ค๋กœ ์ด๋ฃจ์–ด์ง„ ์‚ฌ๊ฐํ˜• ๋ชจ์–‘์˜ ํŒ์ด ์žˆ๊ณ , ๊ทธ ์œ„์— ์–‡์€ ์น˜์ฆˆ(ํšŒ์ƒ‰์œผ๋กœ ํ‘œ์‹œ๋œ ๋ถ€๋ถ„)๊ฐ€ ๋†“์—ฌ ์žˆ๋‹ค. ํŒ์˜ ๊ฐ€์žฅ์ž๋ฆฌ(<๊ทธ๋ฆผ 1>์—์„œ ๋„ค๋ชจ ์นธ์— X์นœ ๋ถ€๋ถ„)์—๋Š” ์น˜์ฆˆ๊ฐ€ ๋†“

www.acmicpc.net

 

 ๋‚˜์˜ ํ’€์ด

 

์Šค์Šค๋กœ์˜ ๊ธฐ๋ณธ๊ธฐ๊ฐ€ ๋งค์šฐ๋งค์šฐ ๋ถ€์กฑํ•˜๋‹ค๊ณ  ๋Š๋‚€ ๋ฌธ์ œ์˜€๋‹ค.

 

๋ฌธ์ œ๋ฅผ ํ‘ธ๋Š”๋ฐ ์ƒ๋‹นํžˆ ์˜ค๋žœ์‹œ๊ฐ„์ด ๊ฑธ๋ ธ๋Š”๋ฐ ๊ทธ ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

1. ๋ชจ๋“  ๊ณต๊ธฐ์ค‘์— ๋…ธ์ถœ๋œ ์น˜์ฆˆ๊ฐ€ ์•„๋‹Œ ์™ธ๋ถ€๊ณต๊ธฐ์— ๋…ธ์ถœ๋œ ์น˜์ฆˆ๋งŒ์ด ๋…น๋Š”๋‹ค๋Š” ์‚ฌ์‹ค

2. ์™ธ๋ถ€ ๊ณต๊ธฐ์™€ ๋‚ด๋ถ€๊ณต๊ธฐ๋ฅผ ์–ด๋–ป๊ฒŒ ๋‚˜๋ˆŒ์ง€

3. ์™ธ๋ถ€๊ณต๊ธฐ์— ์˜ํ•ด ๋…น์€ ์น˜์ฆˆ ์ดํ›„์— ์ƒ๊ธด ๊ณต๊ธฐ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ.

 

๋ฌด์—‡๋ณด๋‹ค ์ œ์ผ ํฐ ์ด์œ ๋Š” ๋ฌธ์ œ๋ฅผ ์šฐ์Šต๊ฒŒ ์ƒ๊ฐํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ธ ๊ฒƒ ๊ฐ™๋‹ค.

๋ณด์ž๋งˆ์ž ๊ทธ๋ƒฅ ์™„์ „ํƒ์ƒ‰์œผ๋กœ ์™ธ๋ถ€๋งŒ ์ฒดํฌํ•ด์„œ ๋…น์ด๋ฉด ๋˜๊ฒ ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ ์ƒ๊ฐ๋ณด๋‹ค ๊ณ ๋ คํ•  ๊ฒŒ ๋งŽ์•˜๋˜ ๊ฒƒ์ด๋‹ค.

 

ํŠนํžˆ 3๋ฒˆ์ด ์กฐ๊ธˆ ์„ฑ๊ฐ€์…จ๋Š”๋ฐ ์ด๋Š” BFS๋ฅผ ๋Œ๋ฆด๋•Œ๋งˆ๋‹ค visited๋ฅผ ์ดˆ๊ธฐํ™”์‹œํ‚ด์œผ๋กœ์จ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ๋‚˜๋Š” ์™ธ๋ถ€์น˜์ฆˆ๋กœ ๊ฒฐ์ •์ด ๋˜๋ฉด ์ƒˆ๋กœ์šด ์ˆซ์ž๋กœ ๋ฐ”๊ฟ”์„œ ์ฐจ๋ณ„์ ์„ ์ฃผ๊ฑฐ๋‚˜ ์น˜์ฆˆ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ flag๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋Š” ๋“ฑ์˜ ์ข€ ๋” ํ—ท๊ฐˆ๋ฆด๋งŒํ•œ ๊ฒƒ๋“ค์„ ์ถ”๊ฐ€ํ•˜๋ คํ–ˆ๋Š”๋ฐ, ์ด๋ณด๋‹ค๋Š” ๋ฐฉ๋ฌธํ‘œ์‹œ์—ฌ๋ถ€๋Š” ๊ฐ•๋ ฅํ•œ ๋ฐฐ์—ด์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ์ด์šฉํ•ด ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜ flag๋Š” ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด๊ฐ’์— ๋Œ€ํ•ด์„œ ์ฒ˜๋ฆฌํ•จ์œผ๋กœ์จ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜๋Š” ์—ญ๋Ÿ‰์ด ํ•„์š”ํ–ˆ๋‹ค.

 

import Foundation

struct Point {
    let x: Int
    let y: Int
    
    init(_ x: Int, _ y: Int) {
        self.x = x
        self.y = y
    }
    
    var nexts: [Point] {
        return [
            Point(x+1, y),
            Point(x-1, y),
            Point(x, y-1),
            Point(x, y+1)
        ]
    }
}

let input = readLine()!.components(separatedBy:" ").map{Int($0)!}
let row = input[0], col = input[1]
var map = [[Int]]()
var tempMap = [[Int]]()
var visited = [[Bool]](repeating: [Bool](repeating: false, count: col), count: row)
let rowRange = 0...row-1
let colRange = 0...col-1
var result = 0
var cheezeCnt: [Int] = []

for _ in 0..<row {
    map.append(readLine()!.components(separatedBy:" ").map{Int($0)!})
}

var flag = false
while true {
    visited = [[Bool]](repeating: [Bool](repeating: false, count: col), count: row)
    tempMap = map
    BFS(0, 0)
    
    result += 1
    findOuterCheeze()
    
    // ๋ฐ”๊นฅ์น˜์ฆˆ๊ฐ€ ์กด์žฌํ•˜์ง€์•Š๋Š”๋‹ค๋ฉด = ์น˜์ฆˆ๊ฐ€ ๋‹ค ๋–จ์–ด์กŒ๋‹ค๋ฉด
    if !flag {
        break
    } else {
        meltingCheeze()
        map = tempMap
        flag = false
    }
}

print(result-1)
print(cheezeCnt[cheezeCnt.count-1])

// ์ฒ˜์Œ ๋ฐ”๊นฅ๋ฒฝ๋“ค์„ 2๋กœ ์ง€์ •
func BFS(_ x: Int, _ y: Int) {
    visited[x][y] = true
    var queue: [Point] = [Point(x, y)]
    
    while !queue.isEmpty {
        let curr = queue.removeFirst()
        for next in curr.nexts where rowRange ~= next.x && colRange ~= next.y {
            if !visited[next.x][next.y], tempMap[next.x][next.y] == 0 {
                visited[next.x][next.y] = true
                queue.append(next)
            } 
        }
    }
    
}

// ๋ฐ”๊นฅ ์น˜์ฆˆ๋“ค์„ ์ฐพ๋Š” ํ•จ์ˆ˜
func findOuterCheeze() {
    for i in 0..<row-1 {
        for j in 0..<col-1 {
            let p = Point(i, j)
            for next in p.nexts {
                if tempMap[i][j] == 1, tempMap[next.x][next.y] == 0, visited[next.x][next.y] {
                    visited[i][j] = true
                    flag = true
                    break
                }
            }
        }
    }
}

// ์น˜์ฆˆ๋ฅผ ๋…น์ด๋Š” ํ•จ์ˆ˜
func meltingCheeze() {
    var cnt = 0
    for i in 0..<row-1 {
        for j in 0..<col-1 {
            if tempMap[i][j] == 1, visited[i][j] {
                tempMap[i][j] = 0
                cnt += 1
            }
        }
    }
    cheezeCnt.append(cnt)
}

 

 

 ๋‹ค๋ฅธ ์‚ฌ๋žŒ์˜ ํ’€์ด

 

์ด๋ถ„์˜ ํ’€์ด๋Š” ๋‚˜์˜ ํ’€์ด๋ณด๋‹ค ํ›จ์”ฌ ๊น”๋”ํ–ˆ๋‹ค.

์™ธ๋ถ€์˜ ๊ณต๊ธฐ๋ฅผ true๋กœ ํ‘œํ˜„์„ ํ•  ๋•Œ ์น˜์ฆˆ์ธ ๋ถ€๋ถ„์€ ํ์— ์•ˆ๋„ฃ๊ณ  0์œผ๋กœ๋งŒ ๋ฐ”๊ฟˆ์œผ๋กœ์จ(๋ฐฉ๋ฌธํ‘œ์‹œ๋„) ์น˜์ฆˆ์˜€๋˜ ๊ณณ์ด ๊ณต๊ธฐ๋กœ ๋ณ€ํ• ๋•Œ์˜ ๋กœ์ง์„ ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  bfs๋ฅผ ํ˜ธ์ถœํ• ๋•Œ๋งˆ๋‹ค visited๋ฅผ ์ดˆ๊ธฐํ™”์‹œํ‚จ๋‹ค๋Š” ์ ๊ณผ tempArr์„ ๋งŒ๋“ค์ง€์•Š๊ณ  cnt๋ฅผ ๋ฆฌํ„ดํ•จ์œผ๋กœ์จ ์ข…๋ฃŒ์‹œ์ ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ๋„ ์ข‹์€๋ฐฉ๋ฒ•์ด์˜€๋‹ค.

 

import Foundation
let nm = readLine()!.split(separator: " ").map{Int(String($0))!}
let n = nm[0]
let m = nm[1]
var cheeseCnt = [Int]()
var cheeseBoard = [[Int]]()
var time = 0
var cnt = 0
let rowRange = 0...n-1
let colRange = 0...m-1

for _ in 0..<n {
    cheeseBoard.append(readLine()!.split(separator: " ").map{ Int(String($0))! })
}

func bfs() -> Int {
    var visited = Array(repeating: Array(repeating: false, count: m), count: n)
    var queue = [(Int, Int)]()
    queue.append((0, 0))
    visited[0][0] = true
    cnt = 0
    
    while !queue.isEmpty {
        let p = queue.removeFirst()
        let curX = p.0
        let curY = p.1
        
        for next in [(curX+1, curY), (curX-1, curY), (curX, curY-1), (curX, curY+1)] {
            if rowRange ~= next.0, colRange ~= next.1, !visited[next.0][next.1] {
                if cheeseBoard[next.0][next.1] == 0 {
                    visited[next.0][next.1] = true
                    queue.append((next.0, next.1))
                } else if cheeseBoard[next.0][next.1] == 1 {
                    visited[next.0][next.1] = true
                    cheeseBoard[next.0][next.1] = 0
                    cnt += 1
                }
            }
        }
    }
    cheeseCnt.append(cnt)
    return cnt
}

while true {
    time += 1
    cnt = bfs()
    if cnt == 0 {
        break
    }
}

print(time-1)
print(cheeseCnt[cheeseCnt.count-2])