[BOJ] 백준 2437번 : 저울 (JAVA)
문제의 링크 : https://www.acmicpc.net/problem/2437
문제
하나의 양팔 저울을 이용하여 물건의 무게를 측정하려고 한다. 이 저울의 양 팔의 끝에는 물건이나 추를 올려놓는 접시가 달려 있고, 양팔의 길이는 같다. 또한, 저울의 한쪽에는 저울추들만 놓을 수 있고, 다른 쪽에는 무게를 측정하려는 물건만 올려놓을 수 있다.
무게가 양의 정수인 N개의 저울추가 주어질 때, 이 추들을 사용하여 측정할 수 없는 양의 정수 무게 중 최솟값을 구하는 프로그램을 작성하시오.
예를 들어, 무게가 각각 3, 1, 6, 2, 7, 30, 1인 7개의 저울추가 주어졌을 때, 이 추들로 측정할 수 없는 양의 정수 무게 중 최솟값은 21이다.
풀이
정렬과 그리디 알고리즘을 활용한 문제였습니다. 제가 생각한 전반적인 로직은 다음과 같습니다.
1. 추는 오름차순으로 정렬되어 있다.
2. 추[0] ~ 추[n-1]의 무게의 합을 m이라고 하면 1~m사이의 무게는 추[0]~추[n-1]을 이용해 만들 수 있다.
경우1. 추[n] <= m + 1
=> 추[0] ~추[n]을 이용해 1~(m+추[n])의 무게를 표현 가능하다.
경우 2. : 추[n] > m+1
=> 추[0]~추[n]을 이용해 m+1의 무게는 표현이 불가능하다.
예를 들어, 추의 무게가 각각 1, 2, 3, 4가 주어져있다고 가정해 봅시다.
처음에 m = 0에서 시작해서 1부터 4까지 차례대로 조건을 비교합니다.
1 <= m + 1에 해당하므로 m = 1이 됩니다.
2 <= m + 1에 해당하므로 m = 3가 됩니다.
3 <= m + 1에 해당하므로 m = 6이 됩니다.
4 <= m + 1에 해당하므로 m = 10가 됩니다.
따라서 주어진 추로 만들 수 있는 최대합은 10이므로 표현할 수 없는 무게의 최솟값은 11, 즉 m + 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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st;
int N = Integer.parseInt(br.readLine());
int[] weight = new int[N]; // 추의 무게
st = new StringTokenizer(br.readLine());
boolean isOne = false; // 입력된 추의 1이 존재하는가?
for (int i = 0; i < N; i++) {
weight[i] = Integer.parseInt(st.nextToken());
if (weight[i] == 1) {
isOne = true;
}
}
if (!isOne) { // 입력된 추의 무게 중 1이 없으면, 표현할 수 없는 가장 최소 무게는 1이다.
bw.write("1\n");
return;
}
Arrays.sort(weight); // 추의 무게를 오름차순으로 정렬한다.
int sum = 0; // 추의 무게의 부분합
for (int i = 0; i < N; i++) {
// 현재 sum은 0부터 i - 1까지 추의 무게의 합이 담겨있다.
// 이것은 1 ~ sum 사이의 무게는 weight[0] ~ weight[i - 1]를 이용해서
// 표현가능하다는 의미이다.
// 만약 weight[i] <= sum + 1이라면, 1 ~ sum + 1 사이의 무게를
// 표현할 수 있게된다는 의미이므로 sum += weight[i]를 해 주면 된다.
// 그렇지 않을 경우, sum + 1은 표현할 수 없으므로 반복문을 종료한다.
if (weight[i] <= sum + 1) {
sum += weight[i];
} else {
break;
}
}
}
}
|
지적 혹은 조언 환영합니다! 언제든지 댓글로 남겨주세요.
'PS > 백준' 카테고리의 다른 글
[BOJ] 백준 10799번 : 쇠막대기 (JAVA) (0) | 2020.05.07 |
---|---|
[BOJ] 백준 1475번 : 방 번호 (JAVA) (1) | 2020.05.06 |
[BOJ] 백준 1476번 : 날짜 계산 (JAVA) (1) | 2020.05.04 |
[BOJ] 백준 2869번 : 달팽이는 올라가고 싶다 (JAVA) (1) | 2020.05.04 |
[BOJ] 백준 18821번 : 홀수와 짝수의 대결 (JAVA) (2) | 2020.05.03 |
댓글