코틀린 코딩테스트 강좌, 세그먼트 트리

세그먼트 트리(Segment Tree)는 배열의 구간 합, 구간 최소값, 구간 최대값 등을 효과적으로 구할 수 있는 자료구조입니다. 이 자료구조는 특히 구간 쿼리와 업데이트가 빈번하게 이루어지는 상황에서 빠른 성능을 발휘합니다. 이 강좌에서는 세그먼트 트리의 기본적인 구조와 구현 방법, 그리고 실제 코딩테스트에서 활용할 수 있는 문제를 다루겠습니다.

세그먼트 트리란?

세그먼트 트리는 배열의 특정 구간에 대한 정보를 저장하기 위한 이진 트리 형태의 자료구조입니다. 각 노드는 특정 구간의 정보를 저장하고, 이를 통해 빠른 쿼리와 업데이트가 가능합니다. 주로 다음과 같은 두 가지 작업을 효율적으로 수행하는 데 사용됩니다.

  • 구간 쿼리(Query): 특정 구간의 합, 최소값, 최대값 등 계산
  • 업데이트(Update): 특정 위치의 값을 변경

세그먼트 트리 구조

세그먼트 트리는 완전 이진 트리로 구성되며, 일반적으로 다음과 같은 방식으로 배열을 구성합니다. 이를 위해, 세그먼트 트리의 각 노드는 부모와 자식 간의 관계를 통해 정의됩니다. 배열의 노드는 다음과 같은 규칙을 따릅니다:

  • 부모 노드는 인덱스 i의 왼쪽 자식이 2*i, 오른쪽 자식이 2*i + 1
  • 리프 노드는 주어진 배열의 각 원소와 상대하는 인덱스에 저장됩니다.

세그먼트 트리 구현

코틀린을 이용한 세그먼트 트리의 구현을 살펴보겠습니다. 먼저, 기본적인 세그먼트 트리 클래스를 정의하고, 초기화, 업데이트 및 쿼리 기능을 구현해 보겠습니다.

1. 세그먼트 트리 클래스 정의


class SegmentTree(private val array: IntArray) {
    private val size: Int = array.size
    private val tree: IntArray = IntArray(4 * size)
    
    init {
        build(0, 0, size - 1)
    }

    private fun build(node: Int, start: Int, end: Int) {
        if (start == end) {
            tree[node] = array[start]
        } else {
            val mid = (start + end) / 2
            build(2 * node + 1, start, mid)
            build(2 * node + 2, mid + 1, end)
            tree[node] = tree[2 * node + 1] + tree[2 * node + 2]
        }
    }

    fun update(index: Int, value: Int) {
        update(0, 0, size - 1, index, value)
    }

    private fun update(node: Int, start: Int, end: Int, index: Int, value: Int) {
        if (start == end) {
            array[index] = value
            tree[node] = value
        } else {
            val mid = (start + end) / 2
            if (index in start..mid) {
                update(2 * node + 1, start, mid, index, value)
            } else {
                update(2 * node + 2, mid + 1, end, index, value)
            }
            tree[node] = tree[2 * node + 1] + tree[2 * node + 2]
        }
    }
    
    fun query(L: Int, R: Int): Int {
        return query(0, 0, size - 1, L, R)
    }

    private fun query(node: Int, start: Int, end: Int, L: Int, R: Int): Int {
        if (R < start || end < L) return 0 // 쿼리 범위와 노드 범위가 겹치지 않음
        if (L <= start && end <= R) return tree[node] // 노드 범위가 쿼리 범위에 포함됨
        val mid = (start + end) / 2
        val leftSum = query(2 * node + 1, start, mid, L, R)
        val rightSum = query(2 * node + 2, mid + 1, end, L, R)
        return leftSum + rightSum
    }
}

2. 사용 예시

위에서 정의한 세그먼트 트리를 사용하여 구간의 합을 구하고 업데이트를 수행하는 예시를 살펴보겠습니다.


fun main() {
    val array = intArrayOf(1, 3, 5, 7, 9, 11)
    val segmentTree = SegmentTree(array)

    println("구간 [1, 3]의 합: ${segmentTree.query(1, 3)}") // 3 + 5 + 7 = 15
    segmentTree.update(1, 10) // array[1]를 10으로 업데이트
    println("업데이트 후 구간 [1, 3]의 합: ${segmentTree.query(1, 3)}") // 10 + 5 + 7 = 22
}

코딩테스트 문제

이제 실제 코딩테스트에서 자주 다뤄지는 문제를 함께 풀어보겠습니다. 아래 문제는 세그먼트 트리를 활용한 응용 문제입니다.

문제: 구간 합과 업데이트

주어진 배열의 특정 구간에 대한 합을 구하는 문제입니다. 추가로 특정 인덱스의 값을 업데이트할 수 있습니다.

문제 설명

- N개의 정수로 이루어진 배열이 주어집니다.
- 이전의 쿼리 결과로부터 Q번 만큼 다음의 작업을 수행합니다.
    1. "1 L R" 쿼리는 배열의 인덱스 L부터 R까지의 합을 요청합니다.
    2. "2 X Y" 쿼리는 인덱스 X의 값을 Y로 업데이트합니다.

입력 형식

- 첫 번째 줄에는 배열의 크기 N과 쿼리의 개수 Q가 주어집니다.
- 두 번째 줄에는 N개의 정수가 주어집니다.
- 그 다음 Q개의 줄에는 쿼리가 주어집니다.

출력 형식

- 각 "1 L R" 쿼리에 대해 구간의 합을 출력합니다.

입력 예시

5 3
1 2 3 4 5
1 1 3
2 1 10
1 1 3

출력 예시

6

문제 풀이

해당 문제를 해결하기 위해 세그먼트 트리를 사용하여 효율적으로 구간 합 쿼리와 업데이트 연산을 실행하도록 구현합니다. 입력으로부터 데이터를 받고 세그먼트 트리를 초기화한 후 쿼리를 처리하는 구조를 가집니다.

구현


fun main() {
    val (n, q) = readLine()!!.split(" ").map { it.toInt() }
    val array = readLine()!!.split(" ").map { it.toInt() }.toIntArray()
    val segmentTree = SegmentTree(array)

    repeat(q) {
        val query = readLine()!!.split(" ").map { it.toInt() }
        if (query[0] == 1) {
            // 구간 합 쿼리
            val sum = segmentTree.query(query[1] - 1, query[2] - 1)
            println(sum)
        } else if (query[0] == 2) {
            // 업데이트 쿼리
            segmentTree.update(query[1] - 1, query[2])
        }
    }
}

결론

이번 강좌에서는 세그먼트 트리의 기본 개념 및 구현 방법을 익혔습니다. 세그먼트 트리는 효율적인 구간 쿼리와 업데이트 구현에 매우 유용한 자료구조이며, 코딩테스트 문제에 자주 출제됩니다. 이번 예제를 통해 세그먼트 트리의 응용을 익혔기를 바라며, 이를 통해 향후 다양한 문제를 해결하는 데 도움이 되길 바랍니다.

코딩테스트 준비 시에는 이러한 다양한 자료구조와 알고리즘을 체계적으로 학습하여 응용 능력을 키우는 것이 중요합니다. 앞으로도 다양한 자료구조와 알고리즘을 통해 더 나은 문제 해결 능력을 갖추시기 바랍니다.

코틀린 코딩테스트 강좌, 선분의 교차 여부 구하기

프로그래밍 대회나 코딩 테스트에서 선분의 교차 여부를 판단하는 문제는 자주 출제되는 주제 중 하나입니다. 이 강좌에서는 Kotlin 언어를 사용하여 선분의 교차 여부를 구하는 방법을 알아보겠습니다. 이 과정을 통해 기하학적 기법과 수학적 사고를 기를 수 있습니다. 또한, 다양한 테스트 케이스를 통해 알고리즘의 정확성을 검증할 것입니다.

문제 설명

두 선분이 주어졌을 때, 이 두 선분이 서로 교차하는지 여부를 판단하는 문제입니다. 선분 A는 점 P1(x1, y1)과 점 P2(x2, y2)로 정의되고, 선분 B는 점 Q1(x3, y3)과 점 Q2(x4, y4)로 정의됩니다. 교차할 경우 “YES”를, 교차하지 않을 경우 “NO”를 출력하여야 합니다.

입력 형식

  • 첫 번째 줄에 선분 A의 두 점 P1, P2를 나타내는 정수 x1, y1, x2, y2가 공백으로 구분되어 주어진다.
  • 두 번째 줄에 선분 B의 두 점 Q1, Q2를 나타내는 정수 x3, y3, x4, y4가 공백으로 구분되어 주어진다.

출력 형식

교차 여부에 따라 “YES” 또는 “NO”를 출력한다.

문제 접근 방법

선분 교차 여부를 판단하기 위해 다음과 같은 절차를 따릅니다:

  1. 두 선분이 교차하기 위해서는 서로의 방향성을 고려해야 합니다.
  2. 두 선분의 각각의 끝 점과 다른 선분의 두 점을 사용하여 방향을 판단합니다.
  3. 선분의 교차 여부는 구간위치를 통해 판단할 수 있습니다.

구체적으로는 선분 A의 점 P1과 P2가 선분 B의 점 Q1과 Q2를 통해 반시계 방향인지 시계 방향인지 판단할 수 있습니다. 이를 통해 교차 여부를 판별할 수 있습니다.

Kotlin 코드 구현

이제 Kotlin 언어로 구현된 코드를 살펴보겠습니다. 아래 코드는 선분 A와 B의 교차 여부를 판단하는 간단한 예시입니다.


fun main() {
    val (x1, y1, x2, y2) = readLine()!!.split(" ").map { it.toInt() }
    val (x3, y3, x4, y4) = readLine()!!.split(" ").map { it.toInt() }

    if (doIntersect(x1, y1, x2, y2, x3, y3, x4, y4)) {
        println("YES")
    } else {
        println("NO")
    }
}

// 두 점의 방향성을 계산
fun orientation(px: Int, py: Int, qx: Int, qy: Int, rx: Int, ry: Int): Int {
    val value = (qy - py) * (rx - qx) - (qx - px) * (ry - qy)
    return when {
        value == 0 -> 0 // 직선
        value > 0 -> 1  // 반시계 방향
        else -> 2       // 시계 방향
    }
}

// 두 선분이 교차하는지 판단하는 함수
fun doIntersect(x1: Int, y1: Int, x2: Int, y2: Int, x3: Int, y3: Int, x4: Int, y4: Int): Boolean {
    val o1 = orientation(x1, y1, x2, y2, x3, y3)
    val o2 = orientation(x1, y1, x2, y2, x4, y4)
    val o3 = orientation(x3, y3, x4, y4, x1, y1)
    val o4 = orientation(x3, y3, x4, y4, x2, y2)

    // 일반적인 경우
    if (o1 != o2 && o3 != o4) return true

    // 선분이 같은 선 위에 있을 때의 예외 처리
    if (o1 == 0 && onSegment(x1, y1, x3, y3, x2, y2)) return true
    if (o2 == 0 && onSegment(x1, y1, x4, y4, x2, y2)) return true
    if (o3 == 0 && onSegment(x3, y3, x1, y1, x4, y4)) return true
    if (o4 == 0 && onSegment(x3, y3, x2, y2, x4, y4)) return true

    return false
}

// 주어진 점이 선분 위에 있는지 판단하는 함수
fun onSegment(px: Int, py: Int, qx: Int, qy: Int, rx: Int, ry: Int): Boolean {
    return (rx <= maxOf(px, qx) && rx >= minOf(px, qx) &&
            ry <= maxOf(py, qy) && ry >= minOf(py, qy))
}

코드 설명

위의 코드는 선분 A와 B의 교차 여부를 판단하는 과정을 구현한 것입니다.

  • orientation 함수: 이 함수는 주어진 세 점 (P, Q, R)의 방향을 계산합니다. 방향에 따라 값이 0 (직선), 1 (반시계 방향), 2 (시계 방향)로 분류됩니다. 이 값은 교차 여부를 판단하는 데 사용됩니다.
  • doIntersect 함수: 이 함수는 각 선분의 방향성을 계산하고, 일반적인 경우와 예외적인 경우를 판단하여 결과를 반환합니다.
  • onSegment 함수: 주어진 점 R이 선분 PQ 위에 있는지를 판단합니다. 선분의 양 끝 점과 비교하여 R의 위치가 선분 내에 포함되는지를 체크합니다.

테스트 케이스

이제 다양한 테스트 케이스를 통해 코드의 정확성을 확인하겠습니다.

  • 테스트 케이스 1: 0 0 2 2 0 2 2 0결과: YES
  • 테스트 케이스 2: 1 1 10 1 1 2 10 2결과: NO
  • 테스트 케이스 3: 10 0 0 10 0 0 10 10결과: YES
  • 테스트 케이스 4: 1 1 3 3 1 3 3 1결과: YES
  • 테스트 케이스 5: 0 0 0 10 0 5 10 5결과: NO

결론

이번 강좌에서는 선분의 교차 여부를 판단하는 효율적인 알고리즘을 Kotlin으로 구현하였습니다. 기하학적인 개념을 기반으로 한 이 문제는 다양한 상황에서 유용하게 활용될 수 있습니다. 적용 가능한 다양한 알고리즘과 기법을 통해 다양한 문제를 풀어보는 경험이 중요합니다.

코드와 테스트 케이스를 실제로 구현하고 실행해보며 알고리즘의 동작 방식을 명확하게 이해하는 것이 중요합니다. 지속적으로 실습하면 기하학적 문제 해결 능력을 키울 수 있습니다.

코틀린 코딩테스트 강좌, 선분 방향 구하기

코딩 테스트는 소프트웨어 개발자로서의 능력을 평가하기 위해 자주 사용되는 방법입니다. 특히 알고리즘 문제 해결 능력은 많은 기업에서 중요하게 생각하는 요소 중 하나입니다. 이번 강좌에서는 선분의 방향을 구하는 문제를 통해 문제 해결 과정을 설명하고, 코틀린 언어를 사용하여 코드를 작성해 보겠습니다.

문제 설명

두 점 (x1, y1)과 (x2, y2)가 주어질 때, 이 두 점으로 이루어진 선분의 방향을 구하는 프로그램을 작성하세요. 여기서 방향은 다음과 같이 정의됩니다.

  • 선분이 시계 방향으로 회전하면 ‘CW’를 출력합니다.
  • 선분이 반시계 방향으로 회전하면 ‘CCW’를 출력합니다.
  • 선분이 일직선 상에 있으면 ‘C’를 출력합니다.

입력

  • 첫 번째 줄: 정수 x1, y1 (첫 번째 점의 좌표)
  • 두 번째 줄: 정수 x2, y2 (두 번째 점의 좌표)

출력

선분의 방향을 위에서 설명한 형태로 출력합니다.

문제 풀이 단계

1. 문제 이해하기

문제를 이해하기 위해 선분의 방향을 정의하는 기하학적 의미를 살펴보겠습니다. 선분은 두 점 사이의 직선을 나타내며, 이 직선이 이루는 각도가 시계 방향인지 반시계 방향인지를 판단할 필요가 있습니다. 두 점을 기준으로 한 세 번째 점을 고려하여 방향을 결정하는 방식이 유용할 것입니다.

2. 벡터의 외적 활용하기

선분의 방향을 판단하기 위해 외적(Cross Product)을 사용할 수 있습니다. 외적을 사용하면 두 벡터가 이루는 각도의 방향을 쉽게 알 수 있습니다. 두 벡터 A와 B의 외적은 다음과 같이 정의됩니다:

A = (x2 – x1, y2 – y1), B = (x, y)

여기서 B는 기준점으로 선택한 점입니다. A가 B의 방향과 이루는 각에 따라 시계 방향, 반시계 방향 또는 일직선 상에 있는지를 판단할 수 있습니다.

3. 코틀린 코드 작성하기


fun determineDirection(x1: Int, y1: Int, x2: Int, y2: Int): String {
    val direction = (x2 - x1) * (y2) - (y2 - y1) * (x2)

    return when {
        direction > 0 -> "CCW"
        direction < 0 -> "CW"
        else -> "C"
    }
}

4. 전체 함수 구현과 테스트하기

전체 프로그램을 구현하여 입력을 받고, 출력하는 형태로 만들어 보겠습니다.


fun main() {
    val (x1, y1) = readLine()!!.split(" ").map { it.toInt() }
    val (x2, y2) = readLine()!!.split(" ").map { it.toInt() }

    println(determineDirection(x1, y1, x2, y2))
}

5. 코드 설명하기

이 코드는 두 점의 좌표를 입력받아 선분의 방향을 출력하는 기능을 수행합니다. ‘determineDirection’ 함수는 외적을 사용해 방향을 계산하고, 결과에 따라 ‘CCW’, ‘CW’ 또는 ‘C’를 반환합니다. ‘main’ 함수에서는 사용자로부터 두 점의 좌표를 입력받고 이를 함수에 전달하여 결과를 출력합니다.

결론

이번 강좌에서는 선분의 방향을 구하는 문제를 해결하는 과정을 살펴보았습니다. 벡터의 외적을 이용하여 방향을 구하는 방법은 기하학적 문제를 해결하는 데에 있어 매우 유용한 접근법입니다. 향후 고급 알고리즘 문제나 기하학 관련 문제를 만날 때, 이러한 기초 지식을 활용하여 더 복잡한 문제들도 해결할 수 있을 것입니다. 코틀린을 사용하여 문제를 해결하는 과정에서 프로그래밍 언어의 문법이나 자료구조의 성질을 깊이 이해하는 데 도움이 되었기를 바랍니다.

참고문헌

  • 알고리즘 문제 해결 전략 – 저자: 구종만
  • 코틀린 프로그래밍 – 저자: 제이슨. 에드먼드

이 포스팅이 흥미롭고 유익하셨다면, 다른 강좌들도 확인해 보시기 바랍니다!

코틀린 코딩테스트 강좌, 선분을 그룹으로 나누기

문제 설명

선분의 집합이 주어졌을 때, 서로 겹치지 않도록 선분을 그룹으로 나누는 문제입니다.
각 선분은 시작점과 끝점으로 정의됩니다. 선분들 사이에 겹치는 부분이 있으면 같은 그룹에 속해야 하며,
겹치지 않는 선분들은 다른 그룹에 속해야 합니다.

입력

  • 첫 번째 줄에는 선분의 개수 N (1 ≤ N ≤ 100,000)이 주어집니다.
  • 두 번째 줄부터 N개의 줄에 각각의 선분의 시작점 l과 끝점 r (l <= r)이 주어집니다.

출력

총 필요한 그룹의 수를 출력합니다.

예제 입력

        5
        1 3
        2 5
        6 8
        7 10
        11 15
        

예제 출력

        3
        

설명

주어진 선분들을 보면, 첫 번째와 두 번째 선분은 겹치므로 같은 그룹에 속합니다.
세 번째와 네 번째 선분도 겹치므로 둘은 같은 그룹에 속하고,
마지막 선분은 다른 그룹에 속하므로 총 3개의 그룹이 필요합니다.

해결 방법

이 문제를 해결하기 위해 올바른 접근 방식은 선분을 정렬한 후,
서로 겹치는 선분을 순차적으로 비교하여 그룹을 생성하는 것입니다.
다음과 같은 단계로 문제를 해결할 수 있습니다.

1단계: 입력 받기

선분을 리스트로 입력받습니다. 각 선분은 쌍으로 이루어져 있으므로
Pair 클래스를 사용하여 선분을 저장합니다.

2단계: 선분 정렬

선분들을 정렬하는 기준은 시작점입니다.
시작점이 작은 순서로 정렬한 후, 만약 시작점이 같다면 끝점이 짧은 것이 먼저 오도록 정렬합니다.

3단계: 그룹화

정렬된 리스트를 순회하면서 현재 그룹의 마지막 선분과 겹치는지 확인합니다.
겹치면 같은 그룹에 속하게 되고, 겹치지 않으면 새로운 그룹을 시작합니다.

4단계: 결과 출력

최종적으로 그룹의 수를 세어 출력합니다.

코드 예시 (Kotlin)

        data class Segment(val start: Int, val end: Int)

        fun countGroups(segments: List): Int {
            val sortedSegments = segments.sortedWith(compareBy({ it.start }, { it.end }))
            var groupCount = 0
            var maxEnd = -1

            for (segment in sortedSegments) {
                if (segment.start > maxEnd) {
                    groupCount++
                    maxEnd = segment.end
                } else {
                    maxEnd = maxOf(maxEnd, segment.end)
                }
            }
            return groupCount
        }

        fun main() {
            val n = readLine()!!.toInt()
            val segments = List(n) {
                val (l, r) = readLine()!!.split(" ").map { it.toInt() }
                Segment(l, r)
            }
            println(countGroups(segments))
        }
        

결론

이 문제를 통해 선분의 그룹화 문제를 해결하는 방법을 배웠습니다.
정렬과 리스트 순회를 통해 효과적으로 그룹의 수를 구할 수 있습니다.
코틀린을 활용하여 작성한 코드 구조는 재사용성이 높고 이해하기 쉬운 형태로
작성할 수 있었음을 확인했습니다.
코딩테스트에 있어서 선분 문제는 자주 출제되는 유형이므로,
이와 유사한 문제들을 연습해보는 것이 좋습니다.

코틀린 코딩테스트 강좌, 선물 전달하기

취업 면접이나 알고리즘 테스트에서 자주 등장하는 문제들을 풀이하는 과정을 다루는 이 글에서는, ‘선물 전달하기’라는 주제를 통해 코틀린의 기초와 문제 해결 능력을 동시에 키우는 방법을 제시합니다. 이 문제는 그래프 이론의 기본적인 개념을 기반으로 하여, 실생활에서도 적용할 수 있는 로직을 제공합니다.

문제 설명

주어진 배열 gifts에는 N개의 사람과 각 사람에게 전달해야 할 gift의 우선순위가 순서대로 나열되어 있습니다. 각 사람은 특정한 수의 선물을 가지고 있으며, 이 선물은 반드시 상대방에게 전달되어야 합니다. 우리의 목표는 모든 사람이 원하는 선물을 정확히 한 번씩 전달받도록 만들고, 이를 위해 필요한 최소한의 선물 전달 동작을 계산하는 것입니다.

예를 들어, 다음과 같은 입력이 주어진다고 가정합시다:

gifts = [2, 0, 1, 3]

이 경우, 각 사람은 다음과 같은 사람에게 선물을 전달합니다:

  • 사람 0: 사람 2에게 전달
  • 사람 1: 사람 0에게 전달
  • 사람 2: 사람 1에게 전달
  • 사람 3: 자기 자신에게 전달

따라서 동작은 3회가 필요합니다. 이 문제를 해결하기 위한 알고리즘을 코틀린으로 구현해 보겠습니다.

문제 접근 방법

이 문제를 해결하기 위해서는 각 사람의 선물 전달을 명확히 이해하고, 전달적 순환구조를 파악해야 합니다. 간단한 예외 처리를 통해 만약 어떤 사람이 선물을 전달할 필요가 없다면 그를 건너뛰는 방식으로 접근할 수 있습니다.

접근 방법

  1. 입력 배열 gifts의 길이를 N이라고 정의합니다.
  2. 각 사람이 전달해야 할 선물의 방향이 어떤지 확인합니다.
  3. 모든 사람을 방문하여 선물을 전달하는 과정을 시뮬레이션합니다.
  4. 그룹의 크기를 세어 받은 선물의 순환을 파악합니다.
  5. 최종적으로 필요한 최소한의 전달 동작 수를 계산합니다.

코드 구현

다음은 위 접근 방법에 따라 구현된 코틀린 코드입니다:

fun minGiftTransfers(gifts: IntArray): Int {
    val visited = BooleanArray(gifts.size)
    var transfers = 0

    for (i in gifts.indices) {
        if (!visited[i]) {
            var current = i
            var cycleSize = 0

            do {
                visited[current] = true
                current = gifts[current]
                cycleSize++
            } while (current != i)

            // 축을 제외 (1개는 서로 선물 전달)
            if (cycleSize > 1) {
                transfers += (cycleSize - 1)
            }
        }
    }

    return transfers
}

// 테스트 케이스
fun main() {
    val gifts = intArrayOf(2, 0, 1, 3)
    println("선물 전달에 필요한 최소 동작 수는: ${minGiftTransfers(gifts)}")
}

테스트 케이스

주어진 함수를 테스트하기 위해 다음과 같은 다양한 테스트 케이스를 작성해보았습니다:

  • 테스트 1: 입력 gifts = [1, 0]
    expected output = 1 (사람 0이 사람 1에게 선물을 전달)
  • 테스트 2: 입력 gifts = [1, 2, 0]
    expected output = 1 (3사람이 서로 연결됨)
  • 테스트 3: 입력 gifts = [1, 2, 3, 4, 0]
    expected output = 4 (모두 다른 사람에게 전달)
  • 테스트 4: 입력 gifts = [0, 1, 2, 3, 4]
    expected output = 0 (자기 자신에게 전달)

결론

이번 강좌에서는 코틀린을 사용하여 ‘선물 전달하기’ 문제를 해결하는 과정을 살펴보았습니다. 알고리즘 문제를 해결하기 위해서는 문제의 요구 사항과 제약 조건을 명확히 인지하고, 이를 효율적으로 처리할 수 있는 방법을 모색하는 것이 중요합니다. 이 과정을 통해 kotlin의 기초 문법을 복습함과 동시에 로직 구성 능력을 기를 수 있었습니다.

기타 관련 있는 알고리즘 문제를 연습하여 더 많은 경험을 쌓고 알고리즘 테스트에서 경쟁력을 높여보세요!