몰?.루();
백준 15683번 코틀린 본문
dfs를 이용해 브루트포스 방식으로 풀었다.
즉, 카메라를 회전 시킬 수 있는 모든 경우의 수를 다 테스트하며 각 경우에서 가장 사각지대가 적은 경우를 찾아내었다.
import kotlin.math.min
var answer = Int.MAX_VALUE
fun main() {
val (n, m) = readln().split(" ").map { it.toInt() }
val map = ArrayList<IntArray>()
val cameras = ArrayList<Camera>()
repeat(n) { r ->
val arr = readln().split(" ").map { it.toInt() }.toIntArray()
arr.forEachIndexed { c, i ->
if (i in 1 .. 5) {
cameras.add(Camera(i, r, c))
}
}
map.add(arr)
}
dfs(map, cameras, 0)
println(answer)
}
fun dfs(map: ArrayList<IntArray>, cameras: ArrayList<Camera>, cameraNumber: Int) {
if (cameras.size == 0) { // 카메라 한 대도 없을 때 Array OutOfBound 에러 방지
answer = countZeros(map)
return
}
for (direction in 0 until cameras[cameraNumber].directionCount()) { // 카메라 회전 가능 경우의 수 (1번 카메라는 4개, 5번 카메라는 1개)
val newMap = ArrayList<IntArray>()
map.forEach { newMap.add(it.clone()) }
cameras[cameraNumber].simulate(newMap, direction) // 이 카메라가 현재 바라보고 있는 방향에 대해 쳐다볼 수 있는 곳을 7로 칠한다
if (cameraNumber == cameras.lastIndex) { // dfs의 depth가 마지막일 때 최종적으로 맵에서 0의 개수를 세어서 역대 최소값이면 answer에 넣는다
answer = min(answer, countZeros(newMap))
}
for (i in cameraNumber + 1 until cameras.size) { // 이 카메라 뒤에 있는 카메라들을 회전시키는 경우의 수들을 전부 테스트한다
dfs(newMap, cameras, i)
}
}
}
// 맵에 있는 0의 개수를 구한다
fun countZeros(map: ArrayList<IntArray>): Int {
var count = 0
for (arr in map) {
for (i in arr) {
if (i == 0) {
count++
}
}
}
return count
}
class Camera(val type: Int, val r: Int, val c: Int) {
// 현재 카메라가 바라보고 있는 방향에 대해 쳐다볼 수 있는 공간들을 7으로 칠한다
// direction이 1: 위, 2: 오른쪽, 3: 아래쪽, 4: 왼쪽
fun simulate(map: ArrayList<IntArray>, direction: Int) {
when(type) {
1 -> {
checkForward(map, direction)
}
2 -> {
if (direction == 0) { checkForward(map, 0); checkForward(map, 2); }
else if (direction == 1) { checkForward(map, 1); checkForward(map, 3); }
}
3 -> {
if (direction == 0) { checkForward(map, 0); checkForward(map, 1);}
else if (direction == 1) { checkForward(map, 1); checkForward(map, 2); }
else if (direction == 2) { checkForward(map, 2); checkForward(map, 3); }
else if (direction == 3) { checkForward(map, 0); checkForward(map, 3); }
}
4 -> {
if (direction == 0) { checkForward(map, 0); checkForward(map, 1); checkForward(map, 3); }
else if (direction == 1) { checkForward(map, 0); checkForward(map, 1); checkForward(map, 2); }
else if (direction == 2) { checkForward(map, 1); checkForward(map, 2); checkForward(map, 3); }
else if (direction == 3) { checkForward(map, 0); checkForward(map, 2); checkForward(map, 3); }
}
5 -> {
checkForward(map, 0); checkForward(map, 1); checkForward(map, 2); checkForward(map, 3);
}
}
}
// simulate 함수와 다른 점은 checkForward 함수는 한 방향만 고려해서 7로 칠하는 함수라는 점이다
// 따라서 2번 카메라의 direction이 0이라면 2번 카메라는 위와 아래를 동시에 쳐다보고 있다는 뜻이므로
// 2번 카메라의 simulate(0) == checkForward(0) + checkForward(2)와 같다
private fun checkForward(map: ArrayList<IntArray>, direction: Int) {
val dr = intArrayOf(-1, 0, 1, 0)
val dc = intArrayOf(0, 1, 0, -1)
var nextR = r
var nextC = c
while (true) {
nextR += dr[direction]
nextC += dc[direction]
if (nextR in 0 until map.size && nextC in 0 until map[nextR].size) {
if (map[nextR][nextC] == 6) {
break
} else {
map[nextR][nextC] = 7
}
} else {
break
}
}
}
// 1, 3, 4번 카메라는 4방향으로 회전 가능하고 2번 카메라는 2방향, 5번 카메라는 1방향 뿐이다
fun directionCount() = when(type) {
1, 3, 4 -> 4
2 -> 2
else -> 1
}
}
'프로그래밍 > 안드로이드, 코틀린' 카테고리의 다른 글
백준 1182 코틀린 (0) | 2022.11.04 |
---|---|
백준 1722 코틀린 (0) | 2022.10.31 |
백준 1074 코틀린 (0) | 2022.10.06 |
백준 1715 코틀린 (0) | 2022.09.29 |
코틀린 오류 해결법 Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.7.1, expected version is 1.5.1. (0) | 2022.09.02 |
Comments