알고리즘/PS - 백준

[백준 2212 - C++] 센서 : 그리디 알고리즘

excited-hyun 2021. 3. 25. 20:30
반응형

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개의 집중국의 수신 가능 영역의 길이의 합의 최솟값을 출력한다.

 

예제 입력 1 

6

2

1 6 9 3 6 7

예제 출력 1

5

 

풀이

이 문제를 읽고 국어실력에 문제가 있는 걸까 하는 생각을 잠시했다.ㅠㅠㅠ

softeer 코테 풀때도 느꼈지만 문제 해석 능력도 참 중요한듯하다.

처음엔 수신가능 영역이 반지름이라고 생각했었다. 그래서 아무리 생각을 해도 예시에 대해서 5가 나올 방법이 생각이 안났다.

그래서 질의 응답을 보니 나만큼 문제 이해 못하는 사람이 많았다ㅋㅋㅋㅋㅋㅋ

수신가능 영역은 반지름이 아니라 총 길이이다!!!!

 

우선 센서는 정렬이 되어있지 않기 때문에 먼저 정렬을 해주어야한다.

그리고 나서 수신가능 영역길이의 최소합을 구해야한다.

 

우선 오름차순으로 정렬된 각각의 센서사이의 거리를 구한다.

예시의 경우에 대해서 만약 집중국이 하나라면 -> 수신가능 영역의 길이는 8이 되어야 한다.

여기서 집중국이 하나 늘어난다면? -> 센서사이의 거리중에 가장 먼 부분을 뚝 잘라서 두개의 집중국이 관할하게 하면 된다!

즉 하나일때에서 max(센서 사이의 거리)를 빼면 된다.

여기서 또 하나가 늘어난다면? -> 두개일 때와 마찬가지로 또 가장 거리가 먼 부분을 뚝 잘라서 두개의 집중국이 관할하게 하면된다.

 

결과적으로, 센서사이의 거리를 오름차순으로 정렬하고 가장 큰 k-1개의 거리를 제외하고 그 거리들의 합을 구해주면 되는 문제이다.

 

#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>

using namespace std;

int sen[10000];
int diff[10000];

int main(void){
    int n, k;
    int len=0;
    
    scanf("%d %d", &n, &k);
    for(int i=0; i<n; i++){
        scanf("%d", &sen[i]);
    }
    sort(sen, sen+n);
    for(int i=1; i<n; i++){
        diff[i-1] = sen[i]-sen[i-1];
    }
    sort(diff, diff+n);
    for(int i=0; i<n-k+1; i++){
        len += diff[i];
    }
    printf("%d\n", len);
}

 

728x90
반응형