코딩/백준

[백준]2212번 센서

최선을 다하는 2022. 11. 24. 16:42

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

 

2212번: 센서

첫째 줄에 센서의 개수 N(1 ≤ N ≤ 10,000), 둘째 줄에 집중국의 개수 K(1 ≤ K ≤ 1000)가 주어진다. 셋째 줄에는 N개의 센서의 좌표가 한 개의 정수로 N개 주어진다. 각 좌표 사이에는 빈 칸이 하나 있

www.acmicpc.net

문제

한국도로공사는 고속도로의 유비쿼터스화를 위해 고속도로 위에 N개의 센서를 설치하였다. 문제는 이 센서들이 수집한 자료들을 모으고 분석할 몇 개의 집중국을 세우는 일인데, 예산상의 문제로, 고속도로 위에 최대 K개의 집중국을 세울 수 있다고 한다.

각 집중국은 센서의 수신 가능 영역을 조절할 수 있다. 집중국의 수신 가능 영역은 고속도로 상에서 연결된 구간으로 나타나게 된다. N개의 센서가 적어도 하나의 집중국과는 통신이 가능해야 하며, 집중국의 유지비 문제로 인해 각 집중국의 수신 가능 영역의 길이의 합을 최소화해야 한다.

편의를 위해 고속도로는 평면상의 직선이라고 가정하고, 센서들은 이 직선 위의 한 기점인 원점으로부터의 정수 거리의 위치에 놓여 있다고 하자. 따라서, 각 센서의 좌표는 정수 하나로 표현된다. 이 상황에서 각 집중국의 수신 가능영역의 거리의 합의 최솟값을 구하는 프로그램을 작성하시오. 단, 집중국의 수신 가능영역의 길이는 0 이상이며 모든 센서의 좌표가 다를 필요는 없다.

입력

첫째 줄에 센서의 개수 N(1 ≤ N ≤ 10,000), 둘째 줄에 집중국의 개수 K(1 ≤ K ≤ 1000)가 주어진다. 셋째 줄에는 N개의 센서의 좌표가 한 개의 정수로 N개 주어진다. 각 좌표 사이에는 빈 칸이 하나 있으며, 좌표의 절댓값은 1,000,000 이하이다.

출력

첫째 줄에 문제에서 설명한 최대 K개의 집중국의 수신 가능 영역의 길이의 합의 최솟값을 출력한다.


센서를 정렬한 다음 이전 센서와의 거리를 저장한다.

처음에는 하나의 집중국만 사용한다고 하면 이 값을 모두 더한 것이 집중국의 수신 가능 영역의 길이이다.

그 다음 가장 큰 숫자를 기준으로 집중국을 설치하면 집중국 수신 가능 영역에 해당 숫자가 제외되는 것이므로 이전 센서와의 거리를 0으로 최신화한다. 이와 같은 방식으로 (K - 1) 번의 집중국을 설치하면 집중국의 수신 가능 영역의 길이의 합이 최소가 된다.

따라서, 이전 센서와의 거리 중 큰 (K - 1)개의 값을 제외하고 더하면 되기 때문에 정렬을 한 다음 뒤 쪽 (K - 1) 개를 제외하면 답을 구할 수 있다.

#include <iostream>
#include <algorithm>

using namespace std;

int N,K, ans = 0;
int arr[10001];
int dp[10001];

int main (){
    cin >> N >> K;
    for(int i = 0 ; i < N ;i++){
        cin >> arr[i];
    }
    sort(arr, arr+ N);
    dp[0] = 0;
    for(int i = 1; i < N ; i++){
        dp[i] = arr[i] - arr[i - 1];
    }
    sort(dp,dp + N);
    for(int i = 0 ; i < N - K + 1 ; i++)
        ans += dp[i];
    cout << ans;
}

처음 문제의 글을 이해하는 데 오래 걸렸다. 문제가 요구하는 사항을 이해하니 그렇게 어려운 문제 같지는 않아 보였다. 처음에는 그룹을 구하는 문제인 것 같아 disjoint set 문제인 줄 알았지만 막상 떠오르는 풀이는 없었다. 그래서 문제 분류를 보니 그리디였다! 그리디로 풀 생각을 하니 한 덩어리로 본 다음 나눠가는 방식을 생각했고 그림을 그려보니 맞는 풀이인 것 같았다. 문제의 분류를 본 이후로 바로 풀이가 떠올랐지만 문제 분류를 보지 않았다면 꽤 걸렸을 것 같다.  

'코딩 > 백준' 카테고리의 다른 글

[백준]2660번 회장 뽑기 - C++  (1) 2022.11.26
[백준]2170번 선 긋기 - C++  (0) 2022.11.25
[백준] 12904번 A와B - C++  (0) 2022.11.18
[백준] 11000번 강의실 배정 - C++  (0) 2022.11.16
[백준] 2011번 암호코드 - C++  (0) 2022.11.15