백준 2751번: 수 정렬하기2
by Jm Park
문제
N개의 수가 주어졌을 때, 이를 오름차순으로 정렬하는 프로그램을 작성하시오.
입력
첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 숫자가 주어진다. 이 수는 절대값이 1,000,000보다 작거나 같은 정수이다. 수는 중복되지 않는다.
출력
첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다.
예제 입력/출력
입력 | 출력 |
---|---|
5 5 4 3 2 1 |
1 2 3 4 5 |
코드
#include <iostream>
#include <vector>
using namespace std;
vector<int> nums;
// 병합 과정
void mergeSort(int start, int mid, int end) {
vector<int> temp;
int md = mid + 1, st = start;
// start나 mid가 끝점에 도달하면 종료
while (start <= mid && md <= end)
nums[start] > nums[md] ? temp.push_back(nums[md++]) : temp.push_back(nums[start++]);
// 나머지 남은 것들을 temp에 쭉 삽입
while (start <= mid)
temp.push_back(nums[start++]);
while (md <= end)
temp.push_back(nums[md++]);
// temp에 있는 것을 본래의 nums 벡터로 옮김
for (int i = st; i <= end; i++)
nums[i] = temp[i-st];
}
// 분할과정 및 병합 함수 호출
void mergeSortSplit(int start, int end) {
if (start < end) {
int mid = (start + end) / 2;
mergeSortSplit(start, mid);
mergeSortSplit(mid+1, end);
mergeSort(start, mid, end);
}
}
int main() {
int n;
scanf("%d", &n);
nums.resize(n);
for (int i = 0; i < n; i++)
scanf("%d", &nums[i]);
mergeSortSplit(0, n-1);
for (vector<int>::iterator i = nums.begin(); i < nums.end(); i++)
printf("%d\n", *i);
return 0;
}
풀이
언젠간 정렬알고리즘을 제대로 구현해보리라 생각했지만, 그것이 오늘이었다. 위 문제를 풀기위해 정렬알고리즘 중에서 Merge Sort(합병/병합정렬) 알고리즘을 사용하였다.
Merge Sort
시간 복잡도: O(nlogn)
비교기반 정렬 알고리즘으로, 분할 정복 알고리즘의 하나.
이 문제를 풀면서 ‘시간초과’가 많이 발생하는데, 실제로 첫 제출하고 시간초과가 발생하기도 했다. 이에 대한 해결방안 참고 글이 있다. 나의 경우는 cout을 할때 개행문자(\n)가 아닌 endl을 사용해서 발생하였다. 이를 고치니 바로 시간안에 성공하였다.
Subscribe via RSS