https://www.acmicpc.net/problem/2170
문제
매우 큰 도화지에 자를 대고 선을 그으려고 한다. 선을 그을 때에는 자의 한 점에서 다른 한 점까지 긋게 된다. 선을 그을 때에는 이미 선이 있는 위치에 겹쳐서 그릴 수도 있는데, 여러 번 그은 곳과 한 번 그은 곳의 차이를 구별할 수 없다고 하자.
이와 같은 식으로 선을 그었을 때, 그려진 선(들)의 총 길이를 구하는 프로그램을 작성하시오. 선이 여러 번 그려진 곳은 한 번씩만 계산한다.
입력
첫째 줄에 선을 그은 횟수 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)
}
'백준 > 기타' 카테고리의 다른 글
1629번: 곱셈 - Kotlin (분할 정복을 이용한 거듭제곱) (0) | 2023.05.23 |
---|---|
9953번: 문자열 폭발 - Kotlin (스택) (0) | 2023.05.16 |
1644번: 소수의 연속합 - Kotlin (투 포인터, 에라토스테네스의 체) (0) | 2023.03.28 |
2003번: 부분합 - Kotlin (투포인터) (0) | 2023.03.14 |
17298번: 오큰수 - Kotlin (스택) (0) | 2023.03.09 |