2437 - 저울
본문
하나의 양팔 저울을 이용하여 물건의 무게를 측정하려고 한다. 이 저울의 양 팔의 끝에는 물건이나 추를 올려놓는 접시가 달려 있고, 양팔의 길이는 같다. 또한, 저울의 한쪽에는 저울추들만 놓을 수 있고, 다른 쪽에는 무게를 측정하려는 물건만 올려놓을 수 있다.
무게가 양의 정수인 $N$개의 저울추가 주어질 때, 이 추들을 사용하여 측정할 수 없는 양의 정수 무게 중 최솟값을 구하는 프로그램을 작성하시오.
예를 들어, 무게가 각각 $3, 1, 6, 2, 7, 30, 1$인 7개의 저울추가 주어졌을 때, 이 추들로 측정할 수 없는 양의 정수 무게 중 최솟값은 $21$이다.
입력
첫 째 줄에는 저울추의 개수를 나타내는 양의 정수 $N$이 주어진다. $N$은 $1$ 이상 $1\,000$ 이하이다. 둘째 줄에는 저울추의 무게를 나타내는 $N$개의 양의 정수가 빈칸을 사이에 두고 주어진다. 각 추의 무게는 $1$이상 $1\,000\,000$ 이하이다.
출력
첫째 줄에 주어진 추들로 측정할 수 없는 양의 정수 무게 중 최솟값을 출력한다.
제한
시간 제한 | 메모리 제한 |
---|---|
2sec | 128MB |
풀이
답을 알고 나면 생각보다 간단하다. 이해가 잘 안된다면 예시를 하나 크게 만들어두고, 아래 설명처럼 동작할 수 있는지 생각해보자.
한 쪽에 물건을 올리고 다른 쪽에만 추를 올릴 수 있으므로, 사실상 가지고 있는 추만을 이용하여 무게를 만들어야한다. 그러므로, 가지고 있는 추 중에 무게가 $1$인 추가 없다면 무게가 1인 물체를 구별할 수 없을 것이다. 즉 가지고 있는 추 중에서 무게가 $1$인 추가 없다면 계산할 필요도 없다.
그 다음부터는 계산을 좀 해야한다. 우선, 우리가 현재까지 가지고 있는 추들로 최대 $x$까지의 무게를 모두 잴 수 있다고 하자 (그렇다면 $\sum_{i=1}^{n} i = x$일 것이다). 이제 추 하나를 추가하여 $x+1$을 만들어야한다. (만약 못만든다면, 문제의 정답이 $x+1$이 될 것이다). 이번에 추가할 추의 무게를 $a$라고 하자.
만약 $a$가 $1$이라면, 우리는 $x+1$을 만들 수 있다. 이전까지의 추들로 $x$를 만들 수 있으므로, 거기에 $a=1$을 추가하면 $x+1$을 만들 수 있다. 다만 이 추들로는 $x+2$를 만들 수는 없을 것이다.
만약 $a$가 $2$라면, 우리는 $x+1$과 $x+2$를 만들 수 있다. 이전까지의 추들로 $x-1$과 $x$를 만들 수 있으므로, 거기에 $a=2$를 추가하면 $x+1$과 $x+2$를 만들 수 있다. 다만 이 추들로는 $x+3$을 만들 수는 없을 것이다.
위와 같이 $a$를 이용하여 $x+1$을 만들기 위해서는, $a$가 최대 $x+1$까지는 $x+1$을 만들 수 있다. 다만 $a$가 $x+2$가 되면 $x+1$은 만들 수 없다 (이전의 추들로는 $x$까지밖에 못 만들고, $a = x+2$이므로 $x+1$을 만들 수 있는 방법은 없다). 그리고 만약 $a \leq x+1$이라서 $x+1$을 만들 수 있는 상황이 된다면, 이전까지의 추들과 $a$를 이용해 만들 수 있는 최대 무게는 $x+a$가 된다. 그럼 만들 수 없는 무게의 최솟값은 $x+a+1$이 될 것이다.
다만 사용할 추의 순서가 필요하다. 현재 추를 사용하면 무게를 만들 수 없는데, 다른 추를 사용한다면 그 무게를 만들 수 있으면 모든 추에 대한 계산을 해야하므로, 시간이 부족해질 수 있다. 그래서 추의 순서를 두어야하는데, 특정 무게 $x+1$을 만들기 위해서는 $a \leq x+1$이라는 조건만 존재하므로, $a$는 최대한 작은 것들을 고르는 것이 유리하다. 그래서, 추들을 처음에 오름차순으로 정렬해두면 추의 순서는 크게 신경쓰지 않아도 된다.
- 참고 알고리즘 :
코드
사용 언어 : C
최종 수정일 : 2023 / 12 / 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
#define MAX_IDX 1000
int weight[MAX_IDX];
int n;
int cmp(int* a, int* b) { return *a > *b; }
int main() {
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d", weight + i);
}
qsort(weight, n, sizeof(int), cmp);
int ret;
if (weight[0] != 1) {
ret = 1;
} else {
int sum = 1;
for (int i = 1; i < n; ++i) {
if (weight[i] > sum + 1) {
ret = sum + 1;
break;
}
sum += weight[i];
ret = sum + 1;
}
}
printf("%d", ret);
return 0;
}