[BOJ] 18310 - 안테나

Sierra·2022년 2월 12일
0

[BOJ] Greedy

목록 보기
20/33
post-thumbnail

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

문제

일직선 상의 마을에 여러 채의 집이 위치해 있다. 이중에서 특정 위치의 집에 특별히 한 개의 안테나를 설치하기로 결정했다. 효율성을 위해 안테나로부터 모든 집까지의 거리의 총 합이 최소가 되도록 설치하려고 한다. 이 때 안테나는 집이 위치한 곳에만 설치할 수 있고, 논리적으로 동일한 위치에 여러 개의 집이 존재하는 것이 가능하다.

집들의 위치 값이 주어질 때, 안테나를 설치할 위치를 선택하는 프로그램을 작성하시오.

예를 들어 N=4이고, 각 위치가 1, 5, 7, 9일 때를 가정하자.

이 경우 5의 위치에 설치했을 때, 안테나로부터 모든 집까지의 거리의 총 합이 (4+0+2+4)=10으로, 최소가 된다.

입력

첫째 줄에 집의 수 N이 자연수로 주어진다. (1≤N≤200,000) 둘째 줄에 N채의 집에 위치가 공백을 기준으로 구분되어 1이상 100,000이하의 자연수로 주어진다.

출력

첫째 줄에 안테나를 설치할 위치의 값을 출력한다. 단, 안테나를 설치할 수 있는 위치 값으로 여러 개의 값이 도출될 경우 가장 작은 값을 출력한다.

예제 입출력

  • 예제 입력 1
4
5 1 7 9
  • 예제 출력 1
5

Solution

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
    int N;
    int answer;
    cin >> N;
    vector<int> vec(N);
    for(int i = 0; i < N; i++) cin >> vec[i];
    sort(vec.begin(), vec.end());
    if(N % 2 == 1){
        answer = vec[N/2];
    }
    else{
        int mid1, mid2;
        int sum1 = 0, sum2 = 0;
        mid1 = vec[N/2-1];
        mid2 = vec[N/2];
        for(int i = 0; i < N; i++){
            sum1 += abs(vec[i] - mid1);
            sum2 += abs(vec[i] - mid2);
        }
        if(sum1 <= sum2) answer = mid1;
        else answer = mid2;
    }
    cout << answer << '\n';
}

알고리즘 문제 해결 전략 이라는 책이 있다. 이 책을 읽다보면 비슷한 문제가 하나 나와서 생각이 나서 포스팅 해봤다.
일단 입력받은 데이터를 정렬하여 1차원 좌표 평면 형태로 바꿔본다.

그 후는 뻔하다. 현재 데이터가 홀수냐? 짝수냐? 사실 짝수면 더도 덜도말고 중간에 두면 장땡이다.
하지만 홀수라면? 중간이 두개가 되어버린다.
예를 들어 0,1,2,3,4,5,6 이라는 데이터가 있다면 여기서 적당히 7 / 2 = 3 이니까 3 위치가 중간일 수도 있지만, 반드시 그렇지만은 않다. 홀수니까 오히려 딱 중간이 아닐 수도 있는 상황이 생기기에 N / 2 , N / 2 - 1 이 두가지 상황에서 경쟁을 시켜본다.

그 후 무엇이 더 작느냐가 정답이 될 것이다.

profile
블로그 이전합니다 : https://swj-techblog.vercel.app/

0개의 댓글