알고리즘 문제 풀이/백준

[전생했더니 슬라임 연구자였던 건에 대하여 (Hard)/G4/Python3/C++]

제유찬 2024. 11. 25. 18:30

14698번  전생했더니 슬라임 연구자였던 건에 대하여 (Hard) G4

 

문제
안녕? 내 이름은 ntopia! 나는 원래 지구에 살고 있던 평범한 20대 청년이었어. 어느 날 길을 걷다가 괴한의 칼에 찔려 죽어버렸어. 그런데 이게 무슨 일이람! 정신을 차려보니 이 세계에 떨어져 버렸지 뭐야. 여기에서 나는 슬라임을 전문으로 연구하는 슬라임 연구자가 되어버린 것 같아. 나는 지금 아주 중요한 연구를 진행하고 있어. 이 연구가 성공하면 나는 내가 살던 세계로 돌아갈 수 있게 될 거야. 이 연구를 도와주지 않겠니? 이곳의 슬라임은 모두 슬라임 에너지라는 것을 갖고 있고 그 양은 2 이상의 자연수로 표현돼. 나는 슬라임을 합성했을 때 슬라임 에너지가 어떻게 변화하는지에 대해 연구하고 있어. 슬라임 합성 과정은 2마리를 합성해서 1마리를 만들어내는 식으로 이루어져. A만큼의 슬라임 에너지를 가진 슬라임과 B만큼의 슬라임 에너지를 갖고 있는 슬라임이 있었다고 해보자. 이 슬라임 2마리를 합성하면 슬라임 에너지가 A × B 인 슬라임을 만들 수 있어. 그리고 슬라임 합성 기술이 아직 완벽하지 않아서 슬라임을 합성할 때마다 크나큰 전기 에너지가 필요해. 구체적으로, A만큼의 슬라임 에너지를 가진 슬라임과 B만큼의 슬라임 에너지를 가진 슬라임을 합성하려면 A × B 만큼의 전기 에너지가 필요해. 에너지가 4인 슬라임과 에너지가 6인 슬라임을 합성한 모습. 4 × 6의 전기 에너지를 사용해 슬라임 에너지가 24인 슬라임이 합성되었다. 나에겐 지금 N마리의 슬라임이 있어. 이 슬라임들을 모두 적절히 합성해서 1마리의 슬라임으로 만들려고 해. 그런데 내가 소속된 연구소에서 각 합성 단계마다 필요한 전기 에너지들을 모두 곱한 값을 나에게 비용으로 청구하겠다고 했지 뭐야. 그래서 이 값이 최소가 되도록 합성을 적절히 수행하는 것이 내 연구의 목표야. 내 연구를 도와줘! 부탁이야!!

입력
첫 번째 줄에 테스트 케이스의 수 T 가 주어지고, 이어서 T 개의 테스트 케이스가 주어진다.각 테스트 케이스의 첫 번째 줄에는 슬라임의 수 N (1 ≤ N ≤ 60)이 주어지고, 두 번째 줄에는 N 개의 자연수가 주어진다. i번째 자연수 Ci (2 ≤ Ci ≤ 2 × 10^18)는 i번째 슬라임의 슬라임 에너지를 나타낸다. 끝까지 합성하고 난 후에 생기는 슬라임의 에너지의 양이 2 × 10^18 이하라는 것이 보장된다. 모든 테스트 케이스에 대한 N의 총합이 1, 000, 000을 넘지 않음이 보장된다.

출력
각 테스트 케이스마다 슬라임을 끝까지 합성했을 때 청구될 비용의 최솟값을 1, 000, 000, 007로 나눈 나머지를 출력한다. 전기 에너지가 전혀 필요하지 않은 경우엔 1을 출력한다.



 

탐욕적인 방법으로 해결 가능한 문제이다.

우선순위 큐를 사용하여 현재 합성 가능한 슬라임 중 가장 에너지가 작은 2개의 슬라임을 선택하는 방식을 택한다.

 

C++의 경우 최댓값인 2 x 10^18까지 담을 수 있도록 long long으로 선언해야 한다.

 

 

더보기
더보기
import sys
import heapq

t = int(sys.stdin.readline())

for _ in range(t):
    n = int(sys.stdin.readline())
    jellys = list(map(int, sys.stdin.readline().split()))
    cost = 1
    heapq.heapify(jellys)
    
    for i in range(0, n-1, 1):
        a = heapq.heappop(jellys)
        b = heapq.heappop(jellys)
        cost = (cost * a*b)%1000000007
        heapq.heappush(jellys, a*b)
    
    print(cost)​

 

더보기
더보기
#include <iostream>
#include <queue>

using namespace std;

void MakeSlime()
{
    int n; cin>>n;
    priority_queue<long long, vector<long long>, greater<long long>> min_q;
    long long divide = 1000000007;
    while(n--)
    {
        long long v; cin>>v;
        min_q.push(v);
    }

    long long result = 1;
    while(min_q.size()>1)
    {
        long long a = min_q.top();
        min_q.pop();
        long long b = min_q.top();
        min_q.pop();
        result = (result * ((a * b)%divide)) % divide;
        min_q.push(a*b);
    }

    cout<<result<<"\n";
}


int main()
{
    ios_base::sync_with_stdio(false);
    cout.tie(NULL);
    cin.tie(NULL);

    int t; cin>>t;
    while (t--)
        MakeSlime();
    
    return 0;
}

 


'알고리즘 문제 풀이 > 백준' 카테고리의 다른 글

[움직이는 미로 탈출/G3/Python3]  (0) 2024.11.27
[불우이웃돕기/G3/Python3/C++]  (0) 2024.11.26
[파이프 옮기기 2/G4/Python3]  (0) 2024.11.24
[구두 수선공/G1/Python3]  (0) 2024.11.23
[공항/G2/Python3/C++]  (1) 2024.11.22