[BOJ]1655-中間(Python)-優先順位Q(最大お尻、最小お尻)


https://www.acmicpc.net/problem/1655
優先キュー
構造
  • は、優先度の高いデータよりも優先される
  • の優先度を指定しない場合、値が小さいほど優先度が
  • 高くなる.
  • HIPによる実装->heapqモジュールによる
  • は完全なバイナリツリー構造を有し、代表的には最大ヒップ、最小ヒップ
  • である.
  • レイアウトまたは接続リストはなぜXですか?->時間複雑度O(n)
  • 最大ヒップ
    ルートノードは最大値を持ち、親ノードは常に子ノードより大きい
    最小ヒップ
    ルートノードの最小値;親ノードは常に子ノードより小さい
    PythonでHipを実現する3つの方法
    1)直接実施
    2)heapqモジュール
    3)PriorityQueueモジュール
    import heapq
    
    nums = [5, 1, 2, 10, 8]
    heap = []
    for num in nums:
        # heap 삽입 - heapq.heappush(힙이름, 데이터)
        # 우선순위를 주고 싶으면 데이터 부분에 (우선순위, 데이터)의 튜플로 삽입하면 됨
        heapq.heappush(heap, n)
    while heap:
        # heap 삭제 - heapq.heappop(힙이름)
        # 우선순위가 높은 순서대로 즉 데이터가 낮은 순서대로 삭제 됨. (heapq는 기본적으로 최소힙이라서)
        # (우선순위, 데이터) 튜플 구조를 가지는 힙의 경우
        heappop(힙이름)[1]로 데이터 가져올 수 있음
        print(heapq.heappop(heap))
        # 1 2 8 5 10
    最大ヒップ
    nums = [5, 1, 2, 10, 8]
    heap = []
    for num in nums:
        # 작을수록 우선순위 높으므로 마이너스를 붙여 반대로
        heapq.heappush(heap, (-n, n))
    while heap:
        print(heapq.heappop(heap)[1])
        # 10 8 5 2 1
    PriorityQueueの使用
    from queue import PriorityQueue
    Q = PriorityQueue()
    # 원소 삽입
    Q.put(데이터)
    Q.put((우선순위, 데이터))
    # 원소 삭제 - 우선순위 높은 순서대로 삭제
    Q.get() 
    Q.get()[1]

    「真ん中を言う」


    https://www.acmicpc.net/problem/1655
    1.白俊が整数を叫ぶたびに、出現する数字の中間値に現れる
    2.偶数個を叫ぶ場合は中間2個分の小数点を言う
    3.緊張した時間制限
    -->優先キューによる実装
    -->左最大ヒップと右最小ヒップで要素数を比較して中間値を更新

    # 1655 가운데를 말해요 - 우선순위 큐 골드 2 김수민
    import heapq
    import sys
    left_h = [] # 왼쪽 최대 힙
    right_h = [] # 오른쪽 최대 힙
    mid = 0
    N = int(sys.stdin.readline())
    mid = int(sys.stdin.readline())
    print(mid)
    for i in range(1, N):
        n = int(sys.stdin.readline())
        if n > mid: # 중간 값보다 크면
            heapq.heappush(right_h, n) # 오른쪽 큐에 삽입
            if len(left_h) + 1 < len(right_h): # 오른쪽 큐가 원소 2개이상 더 많으면
                heapq.heappush(left_h, (-mid, mid)) # 최소 값 업데이트
                mid = heapq.heappop(right_h)
        else: # 중간 값보다 작으면
            heapq.heappush(left_h, (-n, n)) # 왼쪽 큐에 삽입
            if len(right_h) < len(left_h): # 왼쪽 큐가 원소 1개 이상 더 많으면(중간값 2개일 때 더 작은 값이 mid이므로)
                heapq.heappush(right_h, mid) # 중간 값 업데이트
                mid = heapq.heappop(left_h)[1]
        print(mid)