[C++] 13975번: 파일 합치기 3

2023. 8. 7. 00:44·[게임 개발] 알고리즘 공부/백준

링크

https://www.acmicpc.net/problem/13975

 

13975번: 파일 합치기 3

프로그램은 표준 입력에서 입력 데이터를 받는다. 프로그램의 입력은 T개의 테스트 데이터로 이루어져 있는데, T는 입력의 맨 첫 줄에 주어진다.각 테스트 데이터는 두 개의 행으로 주어지는데,

www.acmicpc.net

문제

소설가인 김대전은 소설을 여러 장(chapter)으로 나누어 쓰는데, 각 장은 각각 다른 파일에 저장하곤 한다. 소설의 모든 장을 쓰고 나서는 각 장이 쓰여진 파일을 합쳐서 최종적으로 소설의 완성본이 들어있는 한 개의 파일을 만든다. 이 과정에서 두 개의 파일을 합쳐서 하나의 임시파일을 만들고, 이 임시파일이나 원래의 파일을 계속 두 개씩 합쳐서 파일을 합쳐나가고, 최종적으로는 하나의 파일로 합친다. 두 개의 파일을 합칠 때 필요한 비용(시간 등)이 두 파일 크기의 합이라고 가정할 때, 최종적인 한 개의 파일을 완성하는데 필요한 비용의 총 합을 계산하시오.

예를 들어, C1, C2, C3, C4가 네 개의 장을 수록하고 있는 파일이고, 파일 크기가 각각 40, 30, 30, 50 이라고 하자. 이 파일들을 합치는 과정에서, 먼저 C2와 C3를 합쳐서 임시파일 X1을 만든다. 이때 비용 60이 필요하다. 그 다음으로 C1과 X1을 합쳐 임시파일 X2를 만들면 비용 100이 필요하다. 최종적으로 X2와 C4를 합쳐 최종파일을 만들면 비용 150이 필요하다. 따라서, 최종의 한 파일을 만드는데 필요한 비용의 합은 60+100+150=310 이다. 다른 방법으로 파일을 합치면 비용을 줄일 수 있다. 먼저 C1과 C2를 합쳐 임시파일 Y1을 만들고, C3와 C4를 합쳐 임시파일 Y2를 만들고, 최종적으로 Y1과 Y2를 합쳐 최종파일을 만들 수 있다. 이때 필요한 총 비용은 70+80+150=300 이다.

소설의 각 장들이 수록되어 있는 파일의 크기가 주어졌을 때, 이 파일들을 하나의 파일로 합칠 때 필요한 최소비용을 계산하는 프로그램을 작성하시오.

입출력 예제

입력

프로그램은 표준 입력에서 입력 데이터를 받는다. 프로그램의 입력은 T개의 테스트 데이터로 이루어져 있는데, T는 입력의 맨 첫 줄에 주어진다.각 테스트 데이터는 두 개의 행으로 주어지는데, 첫 행에는 소설을 구성하는 장의 수를 나타내는 양의 정수 K (3 ≤ K ≤ 1,000,000)가 주어진다. 두 번째 행에는 1장부터 K장까지 수록한 파일의 크기를 나타내는 양의 정수 K개가 주어진다. 파일의 크기는 10,000을 초과하지 않는다.

출력

프로그램은 표준 출력에 출력한다. 각 테스트 데이터마다 정확히 한 행에 출력하는데, 모든 장을 합치는데 필요한 최소비용을 출력한다.

예제 입력 1 복사
2
4
40 30 30 50
15
1 21 3 4 5 35 5 4 3 5 98 21 14 17 32
예제 출력 1 복사
300
826

코드

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <cmath>
#include <queue>
#include <stack>

using namespace std;

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

	int n;
	cin >> n;
	while (n--)
	{
		priority_queue<long long, vector<long long>, greater<long long>> file;
		int k;
		cin >> k;

		for (int i = 0; i < k; i++)
		{
			int temp;
			cin >> temp;
			file.push(temp);
		}

		long long sum = 0;
		while (file.size() != 1)
		{
			long long temp1, temp2;

			temp1 = file.top();
			file.pop();
			temp2 = file.top();
			file.pop();
			file.push(temp1 + temp2);
			sum += temp1 + temp2;
		}

		cout << sum << endl;
	}

	return 0;
}

풀이

  • 그리디 알고리즘과 우선순위 큐를 사용했다.
  • 최소비용을 만들어야 하니 가장 작은 순으로 정렬 후,
    계속해서 가장 작은 두 숫자를 합쳐서 반복해서 더해지는 수가 최소가 되도록 하는것이
    최소비용을 만드는 방법이다.

  • 따라서 우선순위 큐를 이용해 오름차순으로 정렬하여 가장 위에있는 두 수를 더해주고 다시 push한다.
    이 때 더한 수를 sum에 더하고
    모든 과정이 끝난 후 하나의 파일만 남으면 sum을 출력한다.
저작자표시 (새창열림)

'[게임 개발] 알고리즘 공부 > 백준' 카테고리의 다른 글

[C++] 1120번: 문자열  (0) 2023.08.10
[C++] 1051번: 숫자 정사각형  (0) 2023.08.08
[C++] 2141번: 우체국  (0) 2023.08.06
[C++] 1715번: 카드 정렬하기  (0) 2023.08.02
[C++] 12904번: A와 B  (0) 2023.07.31
'[게임 개발] 알고리즘 공부/백준' 카테고리의 다른 글
  • [C++] 1120번: 문자열
  • [C++] 1051번: 숫자 정사각형
  • [C++] 2141번: 우체국
  • [C++] 1715번: 카드 정렬하기
람팜팜~
람팜팜~
:)
  • 람팜팜~
    RumPumPum
    람팜팜~
  • 전체
    오늘
    어제
    • 전체 (123)
      • 🎵 일상 (2)
      • JAVA (5)
        • 김영한의 자바 입문 (3)
      • JavaScript (12)
      • ---------------------------.. (0)
      • [게임 개발] 포트폴리오 (2)
        • RPG (1)
        • 슈터-플랫포머 (1)
      • [게임 개발] 개발 일지 (28)
        • RPG (25)
        • TopDownProject (3)
      • [게임 개발] 언리얼엔진 공부 (9)
        • 이득우의 언리얼 프로그래밍 Part.1 (6)
        • 이득우의 언리얼 프로그래밍 Part.2 (1)
        • 개인 메모 (2)
      • [게임 개발] 알고리즘 공부 (60)
        • 프로그래머스 (8)
        • 백준 (52)
        • 개인 메모 (0)
      • [게임 개발] CPP 공부 (2)
        • 이것이 C++ 이다 (1)
        • Effective C++ (0)
        • Effective Modern C++ (0)
        • 홍정모 그래픽스 새싹코스 (1)
      • [게임 개발] CS 공부 (3)
  • 블로그 메뉴

    • 링크

      • Github
    • 공지사항

    • 인기 글

    • 태그

      역참조
      dfs
      데드락
      스레드
      투포인터
      메모리구조
      브루트포스
      context switching
      슬라이딩 윈도우
      그리디
      참조자
      누적합
      프로세스
      문자열
      해시
      우선순위 큐
      dp
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    람팜팜~
    [C++] 13975번: 파일 합치기 3
    상단으로

    티스토리툴바