๊ธ€ ์ž‘์„ฑ์ž: ์ด์ง€์›๐ŸŒฉ๏ธ

์ค‘๊ฐ„๋ถ€ํ„ฐ ์‹œ๊ฐ„ ์žฌ๋‹ค๊ฐ€ ๋ง์•˜์ง€๋งŒ, ๊ฑฐ์˜ ๋‹ค์„ฏ์‹œ๊ฐ„ ๊ฐ€๊นŒ์ด ๋ถ™์žก์•˜๋‹ค. ใ… ใ… 

ํ’€๊ธฐ ์‹œ์ž‘ํ•œ ์ง€ ๋‘ ์‹œ๊ฐ„์ด ์ง€๋‚ฌ์„ ๋•Œ ์ฏ”์Œ์— ์Šฌ๋ž™์— ๋ฌผ์–ด๋ดค๊ณ  ๋‘ ๊ฐ€์ง€ ์กฐ์–ธ์„ ๋“ค์—ˆ๋‹ค.

  1. board ์ „์ฒด๋ฅผ ๋Œ๋ฉด์„œ 2๊ฐ€ ๋‚˜์˜ฌ ๋•Œ๋งˆ๋‹ค BFS๋ฅผ ๋Œ๋ฆฌ๋Š” ๊ฒƒ ๋ณด๋‹ค 2๊ฐ€ ์žˆ๋Š” ์œ„์น˜๋ฅผ ๋ฏธ๋ฆฌ ์ €์žฅํ•ด๋†“๊ณ  BFS๋ฅผ ๋Œ๋ฆฌ๋Š” ๊ฒŒ ๋” ๋‚ซ๋‹ค.
  2. !visited.contains([nx, ny])์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ O(N)์ด๋ฏ€๋กœ ๋” ๋น ๋ฅด๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฐ”๊ฟ”๋ผ.


์กฐ์–ธ ํ•ด์ฃผ์‹  ๋Œ€๋กœ 1, 2๋ฅผ ์ˆ˜์ •ํ–ˆ๋‹ค.

  1. 2๊ฐ€ ์žˆ๋Š” ์œ„์น˜๋ฅผ virusLocation์— ์ €์žฅํ–ˆ๋‹ค.
  2. visited๋ฅผ Set์œผ๋กœ ๋ณ€๊ฒฝํ–ˆ๋‹ค. Set.contains()์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(1)

๋กœ์ปฌ์—์„œ๋Š” ๋ˆˆ์— ๋„๊ฒŒ ์„ฑ๋Šฅ ํ–ฅ์ƒ์ด ์žˆ์—ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ๋ฐฑ์ค€์—์„œ๋Š” ์‹œ๊ฐ„ ์ดˆ๊ณผ์˜€๋‹ค. ๊ทธ๋ž˜์„œ ์Šค์œ„ํ”„ํŠธ๋กœ ํ†ต๊ณผํ•˜์‹  ๋ถ„์˜ ํ’€์ด๋ฅผ ์ฐธ๊ณ ํ–ˆ๋‹ค.


๊ทธ๋ฆฌ๊ณ  ๋‚ด ์ฝ”๋“œ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ ์„ ๋ณ€๊ฒฝํ–ˆ๋‹ค.

  1. ํ•จ์ˆ˜๋ฅผ ๋ถ„๋ฆฌํ–ˆ๋‹ค.
  2. 2์ฐจ์› ๋ฐฐ์—ด๋กœ ์ €์žฅํ–ˆ๋˜ virusLocation์„ [(Int, Int)] ํ˜•ํƒœ๋กœ ์ €์žฅํ–ˆ๋‹ค.
  3. ๋ฐ”์ด๋Ÿฌ์Šค๊ฐ€ ํผ์ ธ๋‚˜๊ฐ€๋Š” bfs()์—์„œ visited๋ฅผ ์—†์• ๋Š” ๋Œ€์‹  copyBoard[nx][ny]๊ฐ€ 0์ธ์ง€ ํ™•์ธํ•˜๋Š” ์กฐ๊ฑด์œผ๋กœ ๋ณ€๊ฒฝํ–ˆ๋‹ค.


์•„์ง๋„ ๋ถ€์กฑํ•œ ๊ฒŒ ๋งŽ๋‹ค๋Š” ๊ฑธ ๋Š๊ผˆ๋‹ค.


๋ฌธ์ œ

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


๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ

Swift

let size = readLine()!.split(separator: " ").map { Int(String($0))! }
let n = size[0]
let m = size[1]
var board = [[Int]]()
for _ in 0..<n {
    let line = readLine()!.split(separator: " ").map { Int(String($0))! }
    board.append(line)
}

var copyBoard = board
var results = [[[Int]]]()
var picked = [[Int]]()
var visited = Array(repeating: Array(repeating: false, count: m), count: n)

func makeWall(toPick: Int) {
    if toPick == 0 {
        results.append(picked) // ์กฐํ•ฉ ์ €์žฅ
        return
    }
    for i in 0..<n {
        for j in 0..<m {
            if board[i][j] != 0 {
                continue
            }
            if visited[i][j] {
                continue
            }

            visited[i][j] = true
            picked.append([i, j])
            makeWall(toPick: toPick - 1)
            picked.removeLast()
            visited[i][j] = false
        }
    }
}

var virusLocation = [(Int, Int)]()
for i in 0..<n {
    for j in 0..<m {
        if board[i][j] == 2 {
            virusLocation.append((i, j))
        }
    }
}

func safeArea() -> Int {
    var count = 0
    for i in 0..<n {
        for j in 0..<m {
            if copyBoard[i][j] == 0 {
                count += 1
            }
        }
    }
    return count
}

let dx = [1, 0, -1, 0]
let dy = [0, 1, 0, -1]
func bfs(_ i: Int, _ j: Int) {
    // ๋ฐ”์ด๋Ÿฌ์Šค๊ฐ€ ํผ์ ธ๋‚˜๊ฐ€๋Š” ์ž‘์—…
    var queue = [(i, j)]

    while !queue.isEmpty {
        let v = queue.removeFirst()
        for k in 0..<4 {
            let nx = v.0 + dx[k]
            let ny = v.1 + dy[k]

            if !(0..<n ~= nx) || !(0..<m ~= ny) || copyBoard[nx][ny] == 1 {
                continue
            }
            if copyBoard[nx][ny] == 0 {
                queue.append((nx, ny))
                copyBoard[nx][ny] = 2
            }
        }
    }
}

makeWall(toPick: 3)
var maxArea = 0
for result in results {
    copyBoard = board
    copyBoard[result[0][0]][result[0][1]] = 1
    copyBoard[result[1][0]][result[1][1]] = 1
    copyBoard[result[2][0]][result[2][1]] = 1

    for virus in virusLocation {
        bfs(virus.0, virus.1)
    }

    maxArea = max(maxArea, safeArea())
}

print(maxArea)
๋ฐ˜์‘ํ˜•