※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 1948번 문제인 임계경로이다.
문제는 아래 링크를 확인하자.
1517번: 버블 소트
첫째 줄에 N(1≤N≤500,000)이 주어진다. 다음 줄에는 N개의 정수로 A[1], A[2], …, A[N]이 주어진다. 각각의 A[i]는 0≤|A[i]|≤1,000,000,000의 범위에 들어있다.
www.acmicpc.net
이 문제는 inversion의 개수를 세는 문제이다. 이번에는 직접 병합정렬(merge sort)를 하면서 inversion의 개수를 직접 세는 방식으로 문제를 풀어보았다.
아래는 제출한 소스코드이다.
#include <iostream>
using std::cin; using std::cout;
int arr[20][500001]; // [깊이][배열]
long long ans = 0;
void mergesort(int L, int R, int d) {
if (L == R) {
arr[d][L] = arr[0][L];
return;
}
else {
int mid = (L + R) / 2;
mergesort(L, mid, d + 1); mergesort(mid + 1, R, d + 1);
int pL = L, pR = mid + 1, index = L;
while (pL <= mid && pR <= R) {
if (arr[d + 1][pL] <= arr[d + 1][pR]) {
arr[d][index] = arr[d + 1][pL]; pL++; index++;
}
else {
arr[d][index] = arr[d + 1][pR]; ans += mid - pL + 1; pR++; index++;
}
}
while (pL <= mid) {
arr[d][index] = arr[d + 1][pL]; pL++; index++;
}
while (pR <= R) {
arr[d][index] = arr[d + 1][pR]; pR++; index++;
}
}
}
int main()
{
std::ios::sync_with_stdio(0);
cin.tie(0);
int N; cin >> N;
for (int i = 1;i <= N;i++) {
int x; cin >> x; arr[0][i] = x;
}
mergesort(1, N, 0);
cout << ans;
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 3010 // C++] 페그 (0) | 2021.04.15 |
---|---|
[BOJ 9345 // C++] 디지털 비디오 디스크(DVDs) (1) | 2021.04.14 |
[BOJ 5676 // C++] 음주 코딩 (0) | 2021.04.12 |
[BOJ 11505 // C++] 구간 곱 구하기 (0) | 2021.04.11 |
[BOJ 12016 // C++] 라운드 로빈 스케줄러 (0) | 2021.04.10 |