본문 바로가기
코딩 이야기/백준

백준 1715

by 꾸욱꾸우욱 2021. 4. 12.

이번 문제는 백준 1715 : 카드 정렬하기 이다.

www.acmicpc.net/problem/1715

 

1715번: 카드 정렬하기

정렬된 두 묶음의 숫자 카드가 있다고 하자. 각 묶음의 카드의 수를 A, B라 하면 보통 두 묶음을 합쳐서 하나로 만드는 데에는 A+B 번의 비교를 해야 한다. 이를테면, 20장의 숫자 카드 묶음과 30장

www.acmicpc.net

입력으로 첫째 줄에 N이 주어진다. (1 ≤ N ≤ 100,000) 이어서 N개의 줄에 걸쳐 숫자 카드 묶음의 각각의 크기가 주어진다. 숫자 카드 묶음의 크기는 1,000보다 작거나 같은 양의 정수이다.

출력으로 첫째 줄에 최소 비교 횟수를 출력한다.

 

카드를 정렬할 때 가장 최소의 비교 횟수를 지니도록 해야 한다. 이는 매 정렬마다 가장 적은 수의 카드 더미 둘을 합치는 방식으로 해결할 수 있다. 그리디 알고리즘을 적용한다면 해당 문제는 쉽게 해결이 가능하다. 매번 정렬할 필요 없이 pop 할 때마다 최소의 값이 나오도록 하기 위해 heap을 사용하였다.

코드는 이러하다.

import heapq

n = int(input())
card = []
for _ in range(n):
    heapq.heappush(card, int(input()))

result = 0

while len(card) != 1:
    one = heapq.heappop(card)
    two = heapq.heappop(card)
    temp = one + two
    result += temp
    heapq.heappush(card, temp)

print(result)

 

우선 heapq를 임포트 하여 사용할 수 있도록 한다.

n을 입력받은 뒤, card 리스트를 선언하여 heapq로 사용될 수 있도록 한다. 이후 반복문을 이용해 card 큐에 입력받은 값을 삽입한다.

이제 card 리스트에 원소가 하나 남을 때까지 반복문을 실행한다. 반복문 내부는 이러하다. 가장 작은 크기를 갖는 카드 더미 두 개를 꺼낸다. 이들의 합을 결과에 더해 준 뒤, 다시 card 큐에 넣어 더미가 합쳐진 채로 들어가도록 한다.

해당 과정을 마무리하면 최종 결과가 출력되게 된다.

(코드길이: 279 byte(s) / 수행 시간: 4920 ms / 메모리: 31672 kb)

 

그리디 알고리즘이 크게 어려운 것은 아니나 합쳐진 카드 더미가 기존에 입력받은 카드들보다 더 커질 수 있다는 점과, heap을 생각하지 못한다면 다소 까다롭게 느껴질 수 있는 문제이다. 다양한 알고리즘에 익숙해지도록 하자. 특히 queue를 이용한 풀이가 더 접근하기 쉬운 경우가 많으므로 바로바로 떠올릴 수 있도록 하자.

'코딩 이야기 > 백준' 카테고리의 다른 글

백준 9252  (0) 2021.03.29
백준 18352  (0) 2021.03.17
백준 1010  (0) 2021.01.31