본문 바로가기
공부/알고리즘 문제풀이 기록

[백준 11286] 절댓값 힙

by 도리언 옐로우 2024. 4. 5.

 

11286번: 절댓값 힙

첫째 줄에 연산의 개수 N(1≤N≤100,000)이 주어진다. 다음 N개의 줄에는 연산에 대한 정보를 나타내는 정수 x가 주어진다. 만약 x가 0이 아니라면 배열에 x라는 값을 넣는(추가하는) 연산이고, x가 0

www.acmicpc.net

알고리즘 : 자료구조, 우선순위큐

난이도 : 실버Ⅰ

 

1. 문제요약

  • '절댓값 힙'을 배열에서 절댓값이 가장 작은 값을 출력하고 그 값을 배열에서 제거하는 연산 pop을 지원하는 자료구조라고 하자. 다만 절댓값이 가장 작은 값이 여러개인 경우에는 가장 작은 수를 출력후 그 값을 배열에서 제거하고, 배열이 비었다면 0을 출력하기로 한다.
  • 첫째 줄에 연산의 개수 N(100,000이하의 자연수)이 주어지고, 다음 N개의 줄에 연산에 대한 정보를 나타내는 정수 x가 주어진다. x가 0이 아니라면 배열에 x를 넣는 연산을 의미하고, x가 0이라면 위에서 정의한 연산 pop을 의미한다.
  • 위와 같은 입력에 대한 출력을 보여주는 프로그램을 작성하면 된다.

2. 아이디어

  • 이 문제는 양수에 대한 힙과 음수에 대한 힙을 따로 관리하는 방법으로 푸는게 정석인 것 같다.
  • 그런데 모든 입력이 정수이기 때문에 음수를 소수로 관리하면 하나의 힙으로도 풀 수 있다.
  • 예를들어 -13이 입력으로 들어오면 양수 13으로 변환시키고 여기서 0.5를 빼서 12.5로 만들수 있다. 이렇게 변환시키면 양수 13과 구별도 되면서 양수13과 함께 존재하는 경우 음수13을 먼저 출력할 수 있게 된다. 

3. 구현과정

  • 힙을 사용하기 위해 heapq를 import하고, 빠른 입력처리를 위해 sys를 import하여 input을 처리해 준다.
  • N을 입력으로 받고 N번 순회를 반복하면서 연산을 나타내는 정수를 tmp에 입력받는다.
  • tmp가 양수라면 그대로 heap에 push해주면 된다.
  • tmp가 음수라면 위의 변환과정을 거쳐 -tmp -0.5를 heap에 push해준다.
  • tmp가 0이라면 이는 heappop을 하여 출력해주는 명령어이다.
    • heap에 원소가 존재하는 지 if문으로 확인한 뒤, heappop을 하여 heap에서 가장 작은 원소를 제거후 tmp2에 저장시킨다.
    • 만약 tmp2가 정수라면 양수이므로 그대로 출력해주고, 정수가 아니라면 음수이므로 다시 원래의 수로 변환시키는 작업을 거친 뒤 출력한다.
    • heap에 원소가 존재하지 않으면 0을 출력한다.

4. 파이썬 코드

import heapq
import sys

input = lambda: sys.stdin.readline().rstrip()
heap_abs = []
N = int(input())
for _ in range(N):
    tmp = int(input())
    if tmp > 0:
        heapq.heappush(heap_abs, tmp)
    elif tmp < 0:
        heapq.heappush(heap_abs, -tmp - 0.5)
    else:
        if heap_abs:
            tmp2 = heapq.heappop(heap_abs)
            print(tmp2 if isinstance(tmp2, int) else int(-tmp2 - 0.5))
        else:
            print(0)

'공부 > 알고리즘 문제풀이 기록' 카테고리의 다른 글

[백준 1019] 책 페이지  (0) 2024.04.09
[백준 1107] 리모컨  (0) 2024.04.09
[백준 1563] 개근상  (0) 2024.04.02
[백준 1737] Pibonacci  (0) 2024.03.30
[백준 1341] 사이좋은 형제  (1) 2024.03.19