백준 24060 - 알고리즘 수업 - 병합 정렬 1
1 minute read
문제링크
문제설명
- 병합정렬로 배열 A를 오름차순 정렬할 때, 병합 단계에서 K번째로 저장되는 정렬된 원소를 찾아라.
- 즉, 각 단계에서 비교연산 후 배열에 새롭게 저장될 때 K번째로 저장되는 원소를 찾는 것이다.
문제접근방향(bokyoung)
- 병합정렬을 재귀호출을 이용하여 구현한다.
- 병합 단계에서 원소의 위치가 정해질 때마다 저장 횟수를 1씩 올린다.
- 저장횟수가 K가 될때, 해당 원소값을 기록해둔다.
- K보다 저장횟수가 작은 경우가 있을 수 있으므로 원소값을 기록해두는 변수의 초기값은 -1로 설정한다.
- 정렬이 완료되면 K번째 저장된 원소를 출력한다.
구현
#include <iostream>
#include <vector>
using namespace std;
int N, K;
int cnt = 0;
int ans = -1;
// A[p...q]와 A[q+1...r]을 병합하여 A[p...r]을 오름차순 정렬된 상태로 만든다.
void merge(vector<int>& A, int p, int q, int r)
{
int i = p, j = q + 1, t = 0;
vector<int> tmp;
while (i <= q && j <= r) {
if (A[i] < A[j])
tmp.push_back(A[i++]);
else
tmp.push_back(A[j++]);
cnt++;
if (cnt == K) // K번째 저장된 수
ans = tmp.back();
}
// 왼쪽 배열 부분이 남은 경우
while (i <= q) {
tmp.push_back(A[i++]);
cnt++;
if (cnt == K) // K번째 저장된 수
ans = tmp.back();
}
// 오른쪽 배열 부분이 남은 경우
while (j <= r) {
tmp.push_back(A[j++]);
cnt++;
if (cnt == K) // K번째 저장된 수
ans = tmp.back();
}
// 결과를 배열 A에 저장
i = p;
while (i <= r)
A[i++] = tmp[t++];
}
// p는 분할된 배열의 좌측 끝, r은 우측 끝을 나타낸다.
void merge_sort(vector<int>& A, int p, int r)
{
if (p < r) {
int q = (p + r) / 2; // 중간 지점을 찾는다.
merge_sort(A, p, q); // 전반부 정렬
merge_sort(A, q + 1, r); // 후반부 정렬
merge(A, p, q, r); // 병합
}
}
int main(void)
{
cin.tie(NULL);
ios_base::sync_with_stdio(false);
cin >> N >> K;
vector<int> A(N);
for (int i = 0; i < N; i++)
cin >> A[i];
merge_sort(A, 0, N-1);
cout << ans << endl;
return 0;
}
Leave a comment