새소식

Algorithm/BOJ

[BOJ] 15903 카드 합체 놀이(Java)

  • -
 

15903번: 카드 합체 놀이

첫 번째 줄에 카드의 개수를 나타내는 수 n(2 ≤ n ≤ 1,000)과 카드 합체를 몇 번 하는지를 나타내는 수 m(0 ≤ m ≤ 15×n)이 주어진다. 두 번째 줄에 맨 처음 카드의 상태를 나타내는 n개의 자연수 a1,

www.acmicpc.net

문제

더보기

석환이는 아기다. 아기 석환이는 자연수가 쓰여져있는 카드를 갖고 다양한 놀이를 하며 노는 것을 좋아한다. 오늘 아기 석환이는 무슨 놀이를 하고 있을까? 바로 카드 합체 놀이이다!

아기 석환이는 자연수가 쓰여진 카드를 n장 갖고 있다. 처음에 i번 카드엔 ai가 쓰여있다. 카드 합체 놀이는 이 카드들을 합체하며 노는 놀이이다. 카드 합체는 다음과 같은 과정으로 이루어진다.

  1. x번 카드와 y번 카드를 골라 그 두 장에 쓰여진 수를 더한 값을 계산한다. (x ≠ y)
  2. 계산한 값을 x번 카드와 y번 카드 두 장 모두에 덮어 쓴다.

이 카드 합체를 총 m번 하면 놀이가 끝난다. m번의 합체를 모두 끝낸 뒤, n장의 카드에 쓰여있는 수를 모두 더한 값이 이 놀이의 점수가 된다. 이 점수를 가장 작게 만드는 것이 놀이의 목표이다.

아기 석환이는 수학을 좋아하긴 하지만, 아직 아기이기 때문에 점수를 얼마나 작게 만들 수 있는지를 알 수는 없었다(어른 석환이는 당연히 쉽게 알 수 있다). 그래서 문제 해결 능력이 뛰어난 여러분에게 도움을 요청했다. 만들 수 있는 가장 작은 점수를 계산하는 프로그램을 만들어보자.

입력

더보기

첫 번째 줄에 카드의 개수를 나타내는 수 n(2 ≤ n ≤ 1,000)과 카드 합체를 몇 번 하는지를 나타내는 수 m(0 ≤ m ≤ 15×n)이 주어진다.

두 번째 줄에 맨 처음 카드의 상태를 나타내는 n개의 자연수 a1, a2, …, an이 공백으로 구분되어 주어진다. (1 ≤ ai ≤ 1,000,000)

출력

더보기

첫 번째 줄에 만들 수 있는 가장 작은 점수를 출력한다.

입출력 예제

더보기
입력
3 1
3 2 6

4 2
4 2 3 1

 

더보기
출력
16

19

 

풀이

접근

문제 그대로 접근하되, 자료형만 신경쓰면 되는 문제였다.

카드 숫자를 PQ에 집어넣고, 두 개씩 꺼내어 더한 후 다시 PQ에 두번 넣어주는 방식으로 풀었다.

 

그리디 문제들을 풀고 있는데, 정렬을 하거나 최대, 최소를 활용해서 풀어야하니

PQ를 많이 쓰는 것 같다.

코드

package boj;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Boj15903_카드합체놀이 {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        // init
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        long sum = 0;
        PriorityQueue<Long> pq = new PriorityQueue<>(); // 작은 것부터 출력

        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < n; i++) {
            pq.offer((long) Integer.parseInt(st.nextToken())); // pq에 집어넣기
        }

        // logic
        for (int i = 0; i < m; i++) {
            long min1 = pq.poll();
            long min2 = pq.poll();

            pq.offer(min1 + min2);
            pq.offer(min1 + min2);
        }

        while(!pq.isEmpty()) {
            sum += pq.poll();
        }

        System.out.println(sum);

    }
}

 

배운점

1. 자료형을 항상 신경쓰자.

'Algorithm > BOJ' 카테고리의 다른 글

[BOJ] 1744 수 묶기(Java)  (0) 2023.12.28
[BOJ] 11000 강의실 배정(Java)  (0) 2023.12.28
[BOJ] 11501 주식(Java)  (2) 2023.12.26
[BOJ] 11399 ATM(Java)  (0) 2023.12.26
[BOJ] 11047 동전 0(Java)  (0) 2023.12.26
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.