λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ’― | λ°±μ€€/😐 | Gold

[Kotlin, G5] λ°±μ€€ 11000번 κ°•μ˜μ‹€ λ°°μ •

by immgga 2025. 1. 18.
λ°˜μ‘ν˜•

좜처: unsplash.com

 

κ°•μ˜μ‹€ λ°°μ •(11000번)

Gold 5

#자료 ꡬ쑰 #그리디 μ•Œκ³ λ¦¬μ¦˜ #μ •λ ¬ #μš°μ„ μˆœμœ„ 큐

https://www.acmicpc.net/problem/11000

 

문제 λ‚΄μš©

 

 

문제 μ ‘κ·Ό

κ°•μ˜μ‹€μ„ μ΅œλŒ€ν•œ 적게 μ‚¬μš©ν•΄ n개의 μˆ˜μ—…μ„ λͺ¨λ‘ 진행해야 ν•œλ‹€.

κ°•μ˜μ˜ μ‹œμž‘ μ‹œκ°„κ³Ό μ’…λ£Œ μ‹œκ°„μ„ μ°Έκ³ ν•΄ λͺ¨λ“  κ°•μ˜λ₯Ό μ§„ν–‰ν•˜λŠ” 데 ν•„μš”ν•œ μ΅œμ†Œ κ°•μ˜μ‹€μ˜ 개수λ₯Ό ꡬ해야 ν•œλ‹€.

 

각각의 κ°•μ˜λ“€ 쀑 κ°•μ˜ μ‹œμž‘ μ‹œκ°„μ΄ κ°•μ˜ μ’…λ£Œ μ‹œκ°„λ³΄λ‹€ μž‘κ±°λ‚˜ 같을 λ•ŒλŠ” ν•œ κ°•μ˜μ‹€μ—μ„œ 같이 듀을 수 μžˆλ‹€.

예λ₯Ό λ“€μ–΄ μ‹œμž‘ μ‹œκ°„μ΄ 1이고 μ’…λ£Œ μ‹œκ°„μ΄ 3인 κ°•μ˜μ™€ μ‹œμž‘ μ‹œκ°„μ΄ 3이고 μ’…λ£Œ μ‹œκ°„μ΄ 5인 κ°•μ˜λŠ” ν•œ κ°•μ˜μ‹€μ—μ„œ 같이 듀을 수 μžˆλ‹€. 

 

κ°•μ˜λ“€ 쀑 제일 λ¨Όμ € μ‹œμž‘ν•˜λŠ” κ°•μ˜λΆ€ν„° μ‹œμž‘ν•΄ ν•œ κ°•μ˜μ‹€μ—μ„œ μ“Έ 수 μžˆλŠ” κ°•μ˜λ“€μ„ λͺ¨λ‘ μ œκ±°ν•˜λ©΄μ„œ 문제λ₯Ό ν•΄κ²°ν•˜λ©΄ λœλ‹€.

예λ₯Ό λ“€μ–΄ λ‹€μŒκ³Ό 같은 μž…λ ₯ μ˜ˆμ œκ°€ μžˆμ„ λ•Œ

3
1 3
2 4
3 5

1에 μ‹œμž‘ν•˜κ³  3에 λλ‚˜λŠ” κ°•μ˜λΆ€ν„° μ‹œμž‘ν•΄ ν•œ κ°•μ˜μ‹€μ—μ„œ μ“Έ 수 μžˆλŠ” κ°•μ˜μΈ 3에 μ‹œμž‘ν•˜κ³  5에 λλ‚˜λŠ” κ°•μ˜λ₯Ό μ œκ±°ν•˜λ©΄ λœλ‹€.

그리고 μœ„ 과정을 λ°˜λ³΅ν•˜λ©΄ ν•„μš”ν•œ μ΅œμ†Œ κ°•μ˜ 수λ₯Ό μ•Œ 수 있게 λœλ‹€.

 

κ°•μ˜μ˜ κ°œμˆ˜κ°€ λ§Žμ€ μΌ€μ΄μŠ€μ—μ„œλŠ” 일일이 μ°ΎλŠ” 방법을 μ‚¬μš©ν•˜λ©΄ μ‹œκ°„ μ΄ˆκ³Όκ°€ λ°œμƒν•  수 μžˆλ‹€.

κ°•μ˜κ°€ μ΅œλŒ€ 20만 κ°œκ°€ 올 수 있기 λ•Œλ¬Έμ— μ‹œκ°„ μ΄ˆκ³Όκ°€ λ°œμƒν•  것이닀.

 

κ·ΈλŸ¬λ―€λ‘œ μ„ νƒλœ κ°•μ˜μ—μ„œ μ‹œμž‘ν•  수 μžˆλŠ” κ°•μ˜λ₯Ό λΉ λ₯΄κ²Œ μ°Ύμ•„μ•Ό ν•˜λŠ”λ° λ‚˜λŠ” 이뢄 탐색을 μ΄μš©ν•΄μ„œ κ°•μ˜λ₯Ό μ°Ύμ•„ μ£Όμ—ˆλ‹€.

 

문제 ν•΄κ²° μ½”λ“œ

더보기
import java.io.BufferedReader
import java.io.InputStreamReader

fun main() {
    val bf = BufferedReader(InputStreamReader(System.`in`))
    val n = bf.readLine().toInt()
    val lecture = mutableListOf<Pair<Int, Int>>()

    for (i in 0 until n) {
        val (s, t) = bf.readLine().split(" ").map { it.toInt() }
        lecture.add(Pair(s, t))
    }

    lecture.sortBy { it.second }
    lecture.sortBy { it.first }

    var classCnt = 1
    var endTime = lecture.first().second
    lecture.removeFirst()

    while (lecture.isNotEmpty()) {
        val bsResIndex = binarySearch(lecture, endTime, 0)

        if (bsResIndex in lecture.indices) {
            endTime = lecture[bsResIndex].second
            lecture.removeAt(bsResIndex)
        } else {
            classCnt++
            endTime = lecture[0].second
            lecture.removeFirst()
        }
    }

    println(classCnt)
}

private fun binarySearch(list: List<Pair<Int, Int>>, endTime: Int, si: Int, ei: Int = list.lastIndex): Int {
    val mi = (si + ei) / 2
    if (si > ei) return si

    return if (list[mi].first >= endTime) binarySearch(list, endTime, si, mi - 1)
    else binarySearch(list, endTime, mi + 1, ei)
}

 

문제 풀이

μš°μ„  이뢄 탐색을 μ‚¬μš©ν•˜κΈ° μœ„ν•΄ κ°•μ˜λ₯Ό μ •λ ¬ν•΄ μ£Όμ—ˆλ‹€.

그리고 정닡은 무쑰건 1 이상이기 λ•Œλ¬Έμ— classCntλ₯Ό 1둜 μ •ν•˜κ³ , 처음 μ„ νƒλœ κ°•μ˜μ˜ μ’…λ£Œ μ‹œκ°„μ„ μ €μž₯ν•  λ³€μˆ˜λ₯Ό λ§Œλ“€μ–΄ μ€€λ‹€.

첫 번째 indexλ₯Ό μ§€μš°κ³  λ°˜λ³΅μ„ μ§„ν–‰ν•œλ‹€.

 

이뢄 탐색을 톡해 endTimeκ³Ό μ‹œμž‘ μ‹œκ°„μ΄ ν¬κ±°λ‚˜ 같은 κ°•μ˜λ“€ 쀑 κ°€μž₯ μž‘μ€ κ°•μ˜μ˜ indexλ₯Ό λΆˆλŸ¬μ™€ 쀬닀.

이뢄 νƒμƒ‰μ˜ κ²°κ³Όκ°€ lecture의 λ²”μœ„λ₯Ό λ²—μ–΄λ‚˜κ²Œ 되면 더 이상 같은 κ°•μ˜μ‹€μ„ μ“Έ 수 μžˆλŠ” κ°•μ˜κ°€ μ—†λ‹€λŠ” 뜻이기 λ•Œλ¬Έμ— ν˜„μž¬ 남은 κ°•μ˜λ“€ 쀑 첫 번째 κ°•μ˜μ˜ μ’…λ£Œ μ‹œκ°„μ„ endTime에 μž¬μ μš©ν•˜κ³  classCntλ₯Ό μ¦κ°€μ‹œν‚¨λ‹€.

첫 번째 값을 μ§€μš°λŠ” 것을 μžŠμ§€ 말자.

 

이뢄 탐색을 톡해 μ •μƒμ μœΌλ‘œ indexλ₯Ό 뢈러온 κ²½μš°μ—λŠ” μ„ νƒλœ index의 κ°•μ˜ μ’…λ£Œ μ‹œκ°„μœΌλ‘œ endTime을 μ •μ˜ν•΄ μ£Όκ³  ν•΄λ‹Ή index의 값을 μ œκ±°ν•œλ‹€.

 

 

문제 ν•΄κ²° κ³Όμ •

이뢄 탐색이 μ•Œκ³ λ¦¬μ¦˜ ν‚€μ›Œλ“œμ—λŠ” μ—†μ—ˆμœΌλ‚˜, 이뢄 탐색을 μ‚¬μš©ν•΄μ„œ ν•΄κ²°ν–ˆλ‹€.

아직 μš°μ„ μˆœμœ„ 큐λ₯Ό μ •ν™•νžˆ λͺ¨λ₯΄κΈ° λ•Œλ¬Έμ— μ–΄λ–»κ²Œ κ΅¬ν˜„ν• κΉŒ μƒκ°ν•˜λ‹€κ°€ 이뢄 탐색을 λ– μ˜¬λ¦¬κ²Œ λ˜μ—ˆλ‹€.

 

아이디어 μžμ²΄λŠ” λ– μ˜¬λ¦¬κΈ°λ„ 어렡지 μ•Šμ•˜κ³ , κ΅¬ν˜„ μžμ²΄λ„ μ–΄λ ΅μ§€λŠ” μ•Šμ•˜λ‹€.

체감 λ‚œμ΄λ„: Silver 1 ~ Gold 5

728x90
λ°˜μ‘ν˜•