Uknow's Lab.
article thumbnail

https://level.goorm.io/l/challenge/goormthon-challenge?utm_source=notion&utm_medium=cta&utm_content=open&_gl=1*1lv0w8b*_gcl_au*MTA2NTY4MTU0My4xNjkyMDE0OTc4 

 

구름LEVEL

난이도별 다양한 문제를 해결함으로써 SW 역량을 향상시킬 수 있습니다.

level.goorm.io

 

 

구름톤 알고리즘 챌린지 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일차 문제가 기대되네요.

profile

Uknow's Lab.

@유노 Uknow

인생은 Byte와 Double 사이 Char다. 아무말이나 해봤습니다.