-
백준 15683 감시Algorithm/BOJ 2020. 7. 16. 13:29728x90
출처: www.acmicpc.net/problem/15683
분류: 완전탐색
접근방식
하.. 코드량이 너무 너무 너무 길었던 문제였습니다.
5개의 CCTV가 있고 각 CCTV는 90도로 회전이 가능합니다.
사각지대가 가장 최소가 되는 경우를 찾는 문제입니다.각 CCTV 의 케이스는
1번 상하좌우 4개
2번 상하, 좌우 2개
3번 4개
4번 4개
5번 1개입니다.
저는 CCTV를 먼저 찾아놓고 CCTV List를 다 탐색할 때 까지 DFS를 돌렸습니다.
CCTV 에 케이스는 많지만 결국 지우는 건 방향에 따라 상하좌우 4가지 이므로 상하좌우 direction을 입력받는 함수를 만들어서 지우고
CCTV 타입별로 상 하 좌 우로 직접 입력해주는 방식을 사용했습니다.더 스마트하게 풀 수도 있을 것 같은데 좀 무식하게 푼 것 같네요ㅠ
board를 계속 복사해서 그런지 시간이 꽤 걸렸네요..
어렵다기보다는 꽤나 귀찮았던 문제였습니다.해결방법
let nm = readLine()!.split(separator: " ").map{Int($0)!} var board = [[Int]]() for _ in 0..<nm[0] { board.append(readLine()!.split(separator: " ").map({Int($0)!})) } var minBlindArea = Int.max typealias CCTV = (r: Int, c: Int, type: Int) enum Direction { case up case down case right case left } var cctvList = [CCTV]() for r in 0..<board.count { for c in 0..<board[0].count { if board[r][c] == 0 || board[r][c] == 6 { continue } cctvList.append(CCTV(r: r, c: c, type: board[r][c])) } } func makeSafeArea(row: Int, col: Int, direction: Direction, board: [[Int]]) -> [[Int]] { var r = row var c = col var board = board switch direction { case .up: while 0..<board.count ~= r-1 { r -= 1 if board[r][c] == 6 { return board } else if board[r][c] == 0 { board[r][c] = -1 } else { continue } } return board case .down: while 0..<board.count ~= r+1 { r += 1 if board[r][c] == 6 { return board } else if board[r][c] == 0 { board[r][c] = -1 } else { continue } } return board case .left: while 0..<board[0].count ~= c-1 { c -= 1 if board[r][c] == 6 { return board } else if board[r][c] == 0 { board[r][c] = -1 } else { continue } } return board case .right: while 0..<board[0].count ~= c+1 { c += 1 if board[r][c] == 6 { return board } else if board[r][c] == 0 { board[r][c] = -1 } else { continue } } return board } } func checked(cctv: CCTV, board: [[Int]]) -> [[[Int]]] { var boards = [[[Int]]]() switch cctv.type { case 1: boards.append(makeSafeArea(row: cctv.r, col: cctv.c, direction: .up, board: board)) boards.append(makeSafeArea(row: cctv.r, col: cctv.c, direction: .down, board: board)) boards.append(makeSafeArea(row: cctv.r, col: cctv.c, direction: .left, board: board)) boards.append(makeSafeArea(row: cctv.r, col: cctv.c, direction: .right, board: board)) case 2: var leftBoard = board leftBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .right, board: leftBoard) leftBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .left, board: leftBoard) boards.append(leftBoard) var upDownBoard = board upDownBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .up, board: upDownBoard) upDownBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .down, board: upDownBoard) boards.append(upDownBoard) case 3: var tempBoard = board tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .up, board: tempBoard) tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .right, board: tempBoard) boards.append(tempBoard) tempBoard = board tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .right, board: tempBoard) tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .down, board: tempBoard) boards.append(tempBoard) tempBoard = board tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .down, board: tempBoard) tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .left, board: tempBoard) boards.append(tempBoard) tempBoard = board tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .left, board: tempBoard) tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .up, board: tempBoard) boards.append(tempBoard) case 4: var tempBoard = board tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .left, board: tempBoard) tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .up, board: tempBoard) tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .right, board: tempBoard) boards.append(tempBoard) tempBoard = board tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .up, board: tempBoard) tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .right, board: tempBoard) tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .down, board: tempBoard) boards.append(tempBoard) tempBoard = board tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .right, board: tempBoard) tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .down, board: tempBoard) tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .left, board: tempBoard) boards.append(tempBoard) tempBoard = board tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .down, board: tempBoard) tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .left, board: tempBoard) tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .up, board: tempBoard) boards.append(tempBoard) case 5: var tempBoard = board tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .left, board: tempBoard) tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .up, board: tempBoard) tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .right, board: tempBoard) tempBoard = makeSafeArea(row: cctv.r, col: cctv.c, direction: .down, board: tempBoard) boards.append(tempBoard) default: break } return boards } func check(index: Int, board origin: [[Int]]) { if index >= cctvList.count { var blind = 0 for row in origin { blind += row.filter({ $0 == 0 }).count } minBlindArea = min(minBlindArea, blind) return } let cctv = cctvList[index] for board in checked(cctv: cctv, board: origin) { check(index: index+1, board: board) } } check(index: 0, board: board) print(minBlindArea)
배운점
하아... 진빠진다..
'Algorithm > BOJ' 카테고리의 다른 글
백준 13460 구슬 탈출 2 (0) 2020.07.24 백준 8980 택배 (0) 2020.07.20 백준 1107 리모컨 (0) 2020.07.16 백준 14500 테트로미노 (0) 2020.07.15 백준 6603 로또 (0) 2020.07.15