Developing Myself Everyday

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

 

2170번: 선 긋기

첫째 줄에 선을 그은 횟수 N (1 ≤ N ≤ 1,000,000)이 주어진다. 다음 N개의 줄에는 선을 그을 때 선택한 두 점의 위치 x, y (-1,000,000,000 ≤ x < y ≤ 1,000,000,000)가 주어진다.

www.acmicpc.net

문제

매우 큰 도화지에 자를 대고 선을 그으려고 한다. 선을 그을 때에는 자의 한 점에서 다른 한 점까지 긋게 된다. 선을 그을 때에는 이미 선이 있는 위치에 겹쳐서 그릴 수도 있는데, 여러 번 그은 곳과 한 번 그은 곳의 차이를 구별할 수 없다고 하자.

이와 같은 식으로 선을 그었을 때, 그려진 선(들)의 총 길이를 구하는 프로그램을 작성하시오. 선이 여러 번 그려진 곳은 한 번씩만 계산한다.

입력

첫째 줄에 선을 그은 횟수 N (1 ≤ N ≤ 1,000,000)이 주어진다. 다음 N개의 줄에는 선을 그을 때 선택한 두 점의 위치 x, y (-1,000,000,000 ≤ x < y ≤ 1,000,000,000)가 주어진다.

출력

첫째 줄에 그은 선의 총 길이를 출력한다.

 

나의 풀이

 이 문제는 스위핑 알고리즘을 사용한 문제이다. 스위핑이란 말 그대로 빗자루질을 하듯이 한쪽에서 다른 한쪽으로 진행해 나가는 방식이다. 처음에 이 문제를 접했을 때에는 visited를 두어 두 점의 사이에 존재하는 숫자들을 전부 체크하고 체크된 visited의 개수를 구하려고 했지만 두 점의 거리가 최대 20억임으로 그만큼의 배열을 선언할 수는 없었다. 그래서 그냥 직관적으로 line 배열의 첫번째 값을 start, end 변수로 두고 다음 점을 해당 변수와 비교해가며 문제를 해결하였다.

import kotlin.math.max

fun main() = with(System.`in`.bufferedReader()) {
    val n = readLine().toInt()
    val line = Array(n) { readLine().split(" ").map { it.toInt() }.toIntArray() }

    line.sortBy { it[0] }
    var start = line[0][0]
    var end = line[0][1]
    var result = 0

    for (i in 1 until line.size) {
        if (line[i][0] <= end) {
            if (line[i][1] >= end)
                end = line[i][1]
        }
        else {
            result += end - start
            start = line[i][0]
            end = line[i][1]
        }
    }
    result += end - start

    println(result)
}

 

profile

Developing Myself Everyday

@배준형

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!