Key idea: Counting sort. Time should be O(N).
Algorithm: Time = O(N).
- Counting each value 1, 2, 3, i.e., Count[1], Count[2], Count[3].
- Count[1] + Count[2] + Count[3] = N
- Target intervals:
- I_1 = [0, Count[1])
- I_2 = [Count[1], Count[1] + Count[2])
- I_3 = [Count[1] + Count[2], Count[1] + Count[2] + Count[3])
- Counting each value on 3 different target intervals.
- Define Count[i][j] = # of value i in the interval I_j.
- Swap i and j in min(Count[i][j], Count[j][i]) times for i ≠ j.
- Swap the rest unsorted values.
- Let T_ij = abs(Count[i][j] - Count[j][i]).
- Property: T_ij = T_jk = T_ki.
- Let T = T_ij = T_jk = T_jk.
- Swap 1 -> 2 -> 3 cyclically: Take 2T times.
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream fout("sort3.out");
ifstream fin("sort3.in");
int N;
fin >> N;
int values[1000] = {0};
int value_counts[3] = {0};
int swapping_map[3][3] = {0};
for (int i = 0; i < N; i++) {
fin >> values[i];
value_counts[values[i] - 1]++;
}
int begin_pos = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < value_counts[i]; j++) {
swapping_map[i][values[begin_pos + j] - 1]++;
}
begin_pos += value_counts[i];
}
int swapping_count = 0;
swapping_count += min(swapping_map[0][1], swapping_map[1][0]); // 1 <-> 2
swapping_count += min(swapping_map[1][2], swapping_map[2][1]); // 2 <-> 3
swapping_count += min(swapping_map[2][0], swapping_map[0][2]); // 3 <-> 1
swapping_count += 2 * abs(swapping_map[0][1] - swapping_map[1][0]); // 1 -> 2 -> 3
fout << swapping_count << '\n';
return 0;
}
沒有留言:
張貼留言