Algorithm/Greedy Algorithm
[백준 1715번] 카드 정렬하기 (Java 풀이)
agility
2022. 2. 14. 19:01
백준알고리즘 1715번 : 카드 정렬하기
Queue와 배열을 동시에 사용하여 풀었다.
처음에는 '받은 숫자들 중 가장 작은 두 숫자는 총 숫자의 갯수-1 만큼, 그 다음 작은 숫자는 총 숫자의 갯수-2만큼..... 제을 큰 숫자는 1만큼 더해주면 아닌가?' 라고 생각했다.
[ 10, 20 ,30, 40 을 받았다고 할때 (10+20) 비교, (10+20+30) 비교, (10+20+30+40) 비교하여
정답이 (10+20)+(10+20+30)+(10+20+30+40) = 190 이 나오는 것처럼 ]
다만 이 논리에는 작은 두 숫자를 더한 값이 새로운 집합에서 최솟값이라는 보장이 없다는 것이다.
예를들어 [ 50, 60, 70, 80 ] 값을 받았다면, (50+60)을 비교한 뒤, [70+80]을 비교해야하는 것이다.
더한 값을 다시 배열에 넣는 방식으로 ArrayList를 사용할수도 있겠지만, 정렬이 너무 잦을 것 같아 포기하고
새로 더한 값은 Queue에 담아서 기존 정렬된 배열과, Queue의 peek 값중 어떤것이 작은 값인가?
를 check하여 비교 대상 2개를 추출하도록 구성하였다.
풀이 과정
1. 배열에 값을 담고 오름차순으로 정렬한다.
2. Queue를 선언한 뒤 배열을 탐색하는 동안, 탐색 대상 값과 Queue의 최상단 값을 비교한다.
3. 최솟값 2개를 더하고, Queue에 담기를 반복한다.
소스 ▽
더보기
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
public class Main {// no1715 카드 정렬하기
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int nums = Integer.parseInt(br.readLine());
int[] arr = new int[nums];
for (int i = 0; i < arr.length; i++) {
arr[i] = Integer.parseInt(br.readLine());
}
Arrays.sort(arr);
Queue<Integer> min = new LinkedList<>();
long ans = 0;
int min1 = 0;
int min2 = 0;
int cnt = 0;
boolean chk = false;
while (cnt != arr.length - 1 || !min.isEmpty()) {
if (min.isEmpty() || (!chk && min.peek() > arr[cnt])) {
min1 = arr[cnt];
cnt++;// 다음 arr로 비교해야함
} else {
min1 = min.poll();
}
if (cnt >= arr.length) {
chk = true;
}
if (cnt == arr.length && min.isEmpty()) {
break;
}
if (min.isEmpty() || (!chk && min.peek() > arr[cnt])) {
min2 = arr[cnt];
cnt++;// 다음 arr로 비교해야함
} else {
min2 = min.poll();
}
if (cnt >= arr.length) {
chk = true;
}
ans += min1 + min2;
min.add(min1 + min2);
}
System.out.println(ans);
}
}