본문 바로가기
카테고리 없음

백준 1377 버블소트 [C++] 풀이 및 코드

by 8ehrmin 2025. 5. 8.

문제

버블 소트 알고리즘을 다음과 같이 C++로 작성했다.

bool changed = false;
for (int i=1; i<=N+1; i++) {
    changed = false;
    for (int j=1; j<=N-i; j++) {
        if (A[j] > A[j+1]) {
            changed = true;
            swap(A[j], A[j+1]);
        }
    }
    if (changed == false) {
        cout << i << '\n';
        break;
    }
}

위 소스에서 N은 배열의 크기이고, A는 정렬해야 하는 배열이다. 배열은 A[1]부터 사용한다.

위와 같은 소스를 실행시켰을 때, 어떤 값이 출력되는지 구해보자.

입력

첫째 줄에 N이 주어진다. N은 500,000보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에 A[1]부터 A[N]까지 하나씩 주어진다. A에 들어있는 수는 1,000,000보다 작거나 같은 자연수 또는 0이다.

출력

정답을 출력한다.

코드

#include<iostream>
#include<vector>
#include<algorithm>
#include<deque>
#include<stack>
#include<queue>

using namespace std;

int main()
{
	int N;
	cin >> N;

	vector<pair<int, int>> A(N);

	
	for (int i = 0; i <N; i++)
	{
		cin >> A[i].first;
		A[i].second = i;
	}
	//A번 코드
	sort(A.begin(), A.end());
	int max = -1;
	for (int i = 0; i < N; i++)
	{
		int min = A[i].second - i ;
		if (min > max) max = min;
	}

	cout << max+1;


	return 0;
}

풀이

먼저 버블 정렬은 다음과 같다.

 

여기서 확인할 수 있는 것은

큰 수 일수록 오른쪽으로 밀려나가게 된다.

 

오름차순 정렬일 경우, 큰 순서대로 먼저 정렬이 된다.

확인하면 다음과 같다.

물론 3회전일 때는 8이 9왼쪽 으로 이동할 것 이고.

4회전일 때는 7이 8왼쪽으로 올 것 이다.

 

그럼 6은 몇번 이동할지 생각 해 보자.

1회전에서는 index 3

2회전에서는 index 2

3회전에서는 index 1

4회전에서는 index 0 

 

총 4번 이동했다.

이 횟수는 버블 정렬의 회전 횟수와 동일하다.

 

왜냐하면 큰 수일수록, 오른쪽으로 한번에 자주 이동하는 경우가 많지만,

왼쪽으로 가는 경우 한 회전에 한번이다. 

 

따라서 문제의 답변을 얻기 위해서는 왼쪽으로 간 횟수를 구하면 된다.

A번 설명

왼쪽으로 간 횟수 중 가장 큰 수가 회전 횟수 일 것 이다.

예를들면, 1이 맨 오른쪽에 있는 경우 왼쪽 숫자가 어쩌건 상관없이, 첫번째 인덱스로 즉 왼쪽으로 이동한 횟수가 가장 클 것이기 때문이고 이것이 회전 수 이기 때문이다.

 

그럼 왼쪽으로 얼마나 갔는지 어떻게 알 수 있을까?

바로 자신의 원본 index에서 현재 위치한 index를 차감시켜 주어야 얼마나 이동했는지 알 수 있다.

 

따라서 이동 횟수(회전 횟수)와 +1을 해야 문제에 대한 답변이 나온다.

왜냐하면 정렬이 완성된 회전 횟수에

완성이 되었는지 체크하는 코드가 있기 때문에

+1을 해주어야 한다.