Algorithm/BOJ
버블 소트 - 1517
jhg0406
2020. 3. 8. 07:39
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
//1517 - 버블 솔트
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int N;
pair<int, int> arr[500000];
struct FenwickTree
{
vector<int> tree;
FenwickTree(int n) : tree(n, 0) {}
int sum(int pos)
{
++pos;
int ret = 0;
while(pos)
{
ret += tree[pos];
pos &= (pos - 1);
}
return ret;
}
void add(int pos, int val)
{
++pos;
while(pos < tree.size())
{
tree[pos] += val;
pos += (pos & -pos);
}
}
};
void init()
{
cin >> N;
for(int i = 0; i<N; ++i)
cin >> arr[i].first, arr[i].second = i;
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0);
init();
sort(arr, arr+N);
FenwickTree fwt(N+1);
long long ans = 0;
for(int i = N-1; i>=0; --i)
{
int t = arr[i].second - fwt.sum(arr[i].second);
fwt.add(arr[i].second, 1);
ans += (i - t);
}
cout << ans;
}
|
cs |
https://www.acmicpc.net/problem/1517
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
버블 소트
버블정렬 알고리즘에 대한 이해가 있어야 되는 문제였습니다.
버블정렬 알고리즘은 맨 마지막부터 맞춰나가는 정렬과 비슷합니다.
즉 전체 배열을 보고 가장 큰것을 맨 마지막으로 이동시키고,
아직 미완성인 배열에서 가장 큰것을 미완성된 배열의 맨 마지막으로 이동시키고
... 와같은 동작을 반복적으로 수행하여 정렬하는 매커니즘을 가집니다.
즉 swap이 일어나는 횟수는 각각 단계의 미완성된 배열에서 가장 큰 값을 가지는 수의 현재위치를 해당 배열의 가장 마지막 위치로 옮길때 일어나는 swap의 횟수를 구해 모두 더해주면 됩니다.
이때 정해진 시간을 맞추기 위해서 부분문제에서 가장 큰 값을 뒤로 옮겼을때 나머지 수들의 위치를 일일히 조정해 주지 않고, 펜윅트리를 이용해 조정해주어 빠르게 계산이 가능하도록 했습니다.