구름톤 알고리즘 챌린지 18일차 : 중첩 점
18일차 문제인 중첩 점입니다.
바둑판 모양의 정사각형이 있습니다.
한 사각형을 중심으로 상,하,좌,우로 직선을 그리는데요.
각 직선이 교차하면서 생기는 점들의 총 개수를 구하는 문제입니다.
각 칸의 점의 개수를 구하는 방법은 간단합니다.
바로 해당 칸의 수직선 * 수평선의 개수입니다.
(3, 2)를 보면 수직선 한 개와 수평선 두 개가 교차하고 있고, 2 * 1 = 2로, 총 두 개의 교차점이 생깁니다.
수직 혹은 수평선만 있는 다른 칸의 경우 0 * 1 = 0으로 교차점이 생기지 않습니다.
val map = Array(n) { Array(n) { Array(2) { 0L } } }
저는 바둑판의 각 칸을 표현하기 위해 n * n 배열과, 각 칸의 수직선/수평선의 개수를 카운트하기 위해 3차원 배열을 생성하였습니다.
map[x][y][0]은 수직선을, map[x][y][1]은 수평선을 표현하기 위해 사용하였습니다.
예를 들어 (3, 2)를 기준으로 위쪽으로 직선을 그었을 경우,
map[2][1][0], map[1][1][0], map[0][1][0]을 하나씩 증가시키고,
(3, 3)을 기준으로 왼쪽으로 직선을 긋는다면
map[2][2][1], map[1][2][1], map[0][2][1]을 하나씩 증가시킵니다.
* 좌측상단의 점이 (1, 1)이기 때문에 (0, 0)으로 만들기 위해 x, y좌표를 -1씩 해주었습니다
전체 소스코드
fun main() = with(System.`in`.bufferedReader()) {
val (n, m) = readLine().split(" ").map(String::toInt)
val map = Array(n) { Array(n) { Array(2) { 0L } } }
repeat(m) {
val yxd = readLine().split(" ")
val y = yxd[0].toInt() - 1
val x = yxd[1].toInt() - 1
val d = yxd[2]
when (d) {
"U" -> for (i in y downTo 0) map[i][x][0]++
"D" -> for (i in y until n) map[i][x][0]++
"L" -> for (i in x downTo 0) map[y][i][1]++
"R" -> for (i in x until n) map[y][i][1]++
}
}
println(map.sumOf { it.sumOf { it[0] * it[1] } })
}
맨 마지막 줄은 각 좌표의 수직, 수평선의 곱의 합을 구하는 부분으로,
var sum = 0
for(i in 0 until n) {
for(j in 0 until n) {
sum += map[i][j][0] * map[i][j][1]
}
}
와 같이 풀어 쓸 수 있습니다.
후기
17일차에 비해 다소 싱거운 느낌이 있었던 문제였습니다.
18일차 문제가 기대되네요.
'코딩테스트 > Kotlin' 카테고리의 다른 글
[백준 16920번] [Kotlin] 확장 게임 (0) | 2023.09.11 |
---|---|
[구름톤 챌린지 19일차] [Kotlin] 대체 경로 (0) | 2023.09.08 |
[백준 20302번] [Kotlin] 민트 초코 (1) | 2023.08.17 |
[백준 25585번] [Java, Kotlin] 86 ─에이티식스─ 1 (0) | 2023.08.16 |
[백준 1331번] [Kotlin] 나이트 투어 (0) | 2023.08.04 |