첫째 줄에 사각 지대의 최소 크기를 출력한다.
내가 푼 풀이
- 아주 정성스럽게 완전탐색을 하였다.
- 오른쪽 왼쪽 위 아래 탐색함수를 구현해보고 이를 재사용하였고, 각각 cctv의 탐색가능방향을 모두 탐색하고 최솟값을 구했다.
import Foundation
let input = readLine()!.split(separator: " ").map{Int(String($0))!}
let N = input[0], M = input[1]
var office = [[Int]]()
var cctvs = [(serial: Int, x: Int, y: Int)]()
var result = Int.max
for i in 0..<N {
office.append(readLine()!.split(separator: " ").map{Int(String($0))!})
for j in 0..<office[i].count {
if office[i][j] != 0 && office[i][j] != 6 {
cctvs.append((serial: office[i][j], x: i, y: j))
}
}
}
func dfs(count: Int, arr: [[Int]]) {
if count == cctvs.count {
result = min(result, sum(arr: arr))
return
}
var cctv = cctvs[count]
if cctv.serial == 1 {
for i in 0..<4 {
dfs(count: count+1, arr: serial1Range(direction: i, loc: (x: cctv.x, y: cctv.y), arr: arr))
}
}
if cctv.serial == 2 {
for i in 0..<2 {
dfs(count: count+1, arr: serial2Range(direction: i, loc: (x: cctv.x, y: cctv.y), arr: arr))
}
}
if cctv.serial == 3 {
for i in 0..<4 {
dfs(count: count+1, arr: serial3Range(direction: i, loc: (x: cctv.x, y: cctv.y), arr: arr))
}
}
if cctv.serial == 4 {
for i in 0..<4 {
dfs(count: count+1, arr: serial4Range(direction: i, loc: (x: cctv.x, y: cctv.y), arr: arr))
}
}
if cctv.serial == 5 {
dfs(count: count+1, arr: serial5Range( loc: (x: cctv.x, y: cctv.y), arr: arr))
}
}
func right(loc: (x: Int, y: Int), arr: [[Int]]) -> [[Int]] {
var arr = arr
for i in loc.y+1..<M {
if arr[loc.x][i] == 6 { break }
if arr[loc.x][i] == 0 { arr[loc.x][i] = -1 }
}
return arr
}
func up(loc: (x: Int, y: Int), arr: [[Int]]) -> [[Int]] {
var arr = arr
for i in (0..<loc.x).reversed() {
if arr[i][loc.y] == 6 { break }
if arr[i][loc.y] == 0 { arr[i][loc.y] = -1}
}
return arr
}
func left(loc: (x: Int, y: Int), arr: [[Int]]) -> [[Int]] {
var arr = arr
for i in (0..<loc.y).reversed() {
if arr[loc.x][i] == 6 { break }
if arr[loc.x][i] == 0 { arr[loc.x][i] = -1 }
}
return arr
}
func down(loc: (x: Int, y: Int), arr: [[Int]]) -> [[Int]] {
var arr = arr
for i in loc.x+1..<N {
if arr[i][loc.y] == 6 { break }
if arr[i][loc.y] == 0 { arr[i][loc.y] = -1}
}
return arr
}
func serial1Range(direction: Int, loc: (x: Int, y: Int), arr: [[Int]]) -> [[Int]] {
var arr = arr
if direction == 0 {
return right(loc: loc, arr: arr)
}
if direction == 1 {
return left(loc: loc, arr: arr)
}
if direction == 2 {
return down(loc: loc, arr: arr)
}
if direction == 3 {
return up(loc: loc, arr: arr)
}
return arr
}
func serial2Range(direction: Int, loc: (x: Int, y: Int), arr: [[Int]]) -> [[Int]] {
var arr = arr
if direction == 0 {
arr = right(loc: loc, arr: arr)
arr = left(loc: loc, arr: arr)
}
if direction == 1 {
arr = up(loc: loc, arr: arr)
arr = down(loc: loc, arr: arr)
}
return arr
}
func serial3Range(direction: Int, loc: (x: Int, y: Int), arr: [[Int]]) -> [[Int]] {
var arr = arr
if direction == 0 {
arr = up(loc: loc, arr: arr)
arr = right(loc: loc, arr: arr)
}
if direction == 1 {
arr = right(loc: loc, arr: arr)
arr = down(loc: loc, arr: arr)
}
if direction == 2 {
arr = down(loc: loc, arr: arr)
arr = left(loc: loc, arr: arr)
}
if direction == 3 {
arr = left(loc: loc, arr: arr)
arr = up(loc: loc, arr: arr)
}
return arr
}
func serial4Range(direction: Int, loc: (x: Int, y: Int), arr: [[Int]]) -> [[Int]] {
var arr = arr
if direction == 0 {
arr = serial2Range(direction: 0, loc: loc, arr: arr)
arr = up(loc: loc, arr: arr)
}
if direction == 1 {
arr = serial2Range(direction: 1, loc: loc, arr: arr)
arr = right(loc: loc, arr: arr)
}
if direction == 2 {
arr = serial2Range(direction: 0, loc: loc, arr: arr)
arr = down(loc: loc, arr: arr)
}
if direction == 3 {
arr = serial2Range(direction: 1, loc: loc, arr: arr)
arr = left(loc: loc, arr: arr)
}
return arr
}
func serial5Range(loc: (x: Int, y: Int), arr: [[Int]]) -> [[Int]] {
var arr = arr
arr = serial2Range(direction: 0, loc: loc, arr: arr)
arr = serial2Range(direction: 1, loc: loc, arr: arr)
return arr
}
func sum(arr: [[Int]]) -> Int{
var sum = 0
for i in 0..<arr.count {
sum += arr[i].filter{ $0 == 0}.count
}
return sum
}
dfs(count: 0, arr: office)
print(result)