QA & Engineering Blog

A Blog about Quality · Automation · Engineering

🏠 홈으로

[Platinum V] 버블 소트 - 1517

문제 링크

성능 요약

메모리: 226092 KB, 시간: 1136 ms

분류

자료 구조, 정렬, 세그먼트 트리, 분할 정복

문제 설명

N개의 수로 이루어진 수열 A[1], A[2], …, A[N]이 있다. 이 수열에 대해서 버블 소트를 수행할 때, Swap이 총 몇 번 발생하는지 알아내는 프로그램을 작성하시오.

버블 소트는 서로 인접해 있는 두 수를 바꿔가며 정렬하는 방법이다. 예를 들어 수열이 3 2 1 이었다고 하자. 이 경우에는 인접해 있는 3, 2가 바뀌어야 하므로 2 3 1 이 된다. 다음으로는 3, 1이 바뀌어야 하므로 2 1 3 이 된다. 다음에는 2, 1이 바뀌어야 하므로 1 2 3 이 된다. 그러면 더 이상 바꿔야 할 경우가 없으므로 정렬이 완료된다.

입력

첫째 줄에 N(1 ≤ N ≤ 500,000)이 주어진다. 다음 줄에는 N개의 정수로 A[1], A[2], …, A[N]이 주어진다. 각각의 A[i]는 0 ≤ |A[i]| ≤ 1,000,000,000의 범위에 들어있다.

출력

첫째 줄에 Swap 횟수를 출력한다

💡 Solutions

📄 버블 소트.py

from collections import deque

N = int(input())

lst = list(map(int,input().split()))
ans = 0

# 원소가 이동하는 부분을 오른쪽에서 왼쪽으로 이동하는 것을 보고 count할 수 있다.
def margesort(start, end):
    global ans
    if not(start < end):
        return [lst[start]]
    mid = (start+end)//2
    left = margesort(start,mid)
    right = margesort(mid+1,end)

    rlt = []

    _left = deque(left)
    _right = deque(right)
    while _left and _right:
        l_now = _left[0]
        r_now = _right[0]

        if l_now <= r_now:
            rlt.append(_left.popleft()) # 왼쪽에 있는 원소를 옮김 <- count 필요없음
        else:
            rlt.append(_right.popleft()) # 오른쪽에 있는 원소를 옮김 <- 왼쪽의 원소 수 만큼 count
            ans += len(_left)
        
    if _left:
        rlt += list(_left)
    if _right:
        rlt += list(_right)

    return rlt


margesort(0, N-1)
print(ans)