1 minute read

2141번 : 우체국

문제 링크

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

문제 설명

수직선과 같은 일직선상에 N개의 마을이 위치해 있다. i번째 마을은 X[i]에 위치해 있으며, A[i]명의 사람이 살고 있다.

이 마을들을 위해서 우체국을 하나 세우려고 하는데, 그 위치를 어느 곳으로 할지를 현재 고민 중이다. 고민 끝에 나라에서는 각 사람들까지의 거리의 합이 최소가 되는 위치에 우체국을 세우기로 결정하였다. 우체국을 세울 위치를 구하는 프로그램을 작성하시오.

각 마을까지의 거리의 합이 아니라, 각 사람까지의 거리의 합임에 유의한다

입력

첫째 줄에 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 N개의 줄에는 X[1], A[1], X[2], A[2], …, X[N], A[N]이 주어진다. 범위는 |X[i]| ≤ 1,000,000,000, 1 ≤ A[i] ≤ 1,000,000,000 이며 모든 입력은 정수이다.

출력

첫째 줄에 우체국의 위치를 출력한다. 가능한 경우가 여러 가지인 경우에는 더 작은 위치를 출력하도록 한다.

문제 풀이

처음에는 특정한 우체국의 위치를 정하고, 앞뒤의 우체국보다 총 거리가 적게 나오면 출력하는 코드로 작성하였으나 시간 초과로 실패

결국 다른 사람의 코드를 찾아보니 마을들을 정렬하고, 앞에서부터 사람수를 세어 총 사람 수의 절반이 넘어가는 시점의 마을에 우체국을 정하는 게 정답이였다. 머리로는 총 사람 수의 절반이 되는 시점이 총 거리가 적게 나오는 방법이라는 생각이 들긴하지만 어떻게 이런 생각을 할 수 있을지 의문인 문제였다.

# 최초 풀이 : 시간 초과로 실패

N = int(input())
arr = []
boundary = [-2, -1, 1, 2]

total_dist = 0
total_person = 0
for _ in range(N) : 
    town, person = map(int, input().split())
    total_dist += abs(town) * person
    total_person += person
    arr.append([town, person])

idx = total_dist // total_person

total_dist = 0
for i in range(N) :
    town, person = arr[i]
    total_dist += abs(idx - town) * person

while True :
    for i in range(len(boundary)) :
        count = 0
        for j in range(N) :
            town, person = arr[j]
            count += abs(idx + boundary[i] - town) * person
            
        if count == total_dist and boundary[i] < 0 :
            idx += boundary[i]
            total_dist = count
            break
            
        elif count < total_dist : 
            idx += boundary[i]
            total_dist = count
            break
    else : 
        print(idx)
        break
# 정답 코드
N = int(input())
arr = []
people = 0

for _ in range(N) :
    arr.append(list(map(int, input().split())))
    people += arr[-1][1]

arr.sort(key = lambda x : x[0])

count = 0
for i in range(N) :
    count += arr[i][1]
    
    if count >= people / 2 :
        print(arr[i][0])
        break

Comments