#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n;
std::vector<std::pair<int, int>> tab;
void add_transition(std::vector<int>& transpoztion, int a, int b) {
transpoztion.push_back(a);
transpoztion.push_back(b);
}
std::vector<int> first_transpoztion;
std::vector<int> second_transpoztion;
void calculate_transition(int* permatation) {
bool* processed = new bool[n];
for (int i = 0; i < n; processed[i++] = false);
int* inversed = new int[n];
for (int i = 0; i < n; inversed[permatation[i]] = i, i++);
for (int i = 0; i < n; i++) {
if (processed[i]) continue;
if (permatation[i] == i) {
processed[i] = true;
continue;
}
if (permatation[permatation[i]] == i) {
add_transition(first_transpoztion, i, permatation[i]);
processed[permatation[i]] = true;
processed[i] = true;
continue;
}
int position_to_fix = i, where_is_right_person = inversed[i];
processed[where_is_right_person] = processed[position_to_fix] = true;
while(true) {
add_transition(second_transpoztion, position_to_fix, where_is_right_person);
add_transition(first_transpoztion, position_to_fix, inversed[where_is_right_person]);
// we want where_is_right_person to be inversed[where_is_right_person]
where_is_right_person = inversed[where_is_right_person];
position_to_fix = permatation[position_to_fix];
processed[where_is_right_person] = processed[position_to_fix] = true;
if (where_is_right_person == position_to_fix) {
break;
}
if (permatation[position_to_fix] == where_is_right_person) {
add_transition(second_transpoztion, position_to_fix, where_is_right_person);
break;
}
}
}
}
void print_transpozition(const std::vector<int>& trans) {
std::cout << trans.size() << endl;
for (int i = 0; i < trans.size(); i+=2) std::cout << (trans[i] + 1) << " ";
for (int i = trans.size() - 1; i > 0; i -= 2) std::cout << (trans[i] + 1) << " ";
std::cout << endl;
}
int main() {
std::cin >> n;
tab.reserve(n);
int height;
for (int i = 0; i < n; i++) {
std::cin >> height;
tab.push_back({ height, i });
}
std::sort(tab.begin(), tab.end());
int *permatation = new int[n];
for (int i = 0; i < n; i++) {
permatation[tab[i].second] = i;
}
calculate_transition(permatation);
if (first_transpoztion.size() == 0) {
std::cout << "0\n";
} else if (second_transpoztion.size() == 0) {
std::cout << "1\n";
print_transpozition(first_transpoztion);
} else {
std::cout << "2\n";
print_transpozition(first_transpoztion);
print_transpozition(second_transpoztion);
}
}
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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | #include <iostream> #include <vector> #include <algorithm> using namespace std; int n; std::vector<std::pair<int, int>> tab; void add_transition(std::vector<int>& transpoztion, int a, int b) { transpoztion.push_back(a); transpoztion.push_back(b); } std::vector<int> first_transpoztion; std::vector<int> second_transpoztion; void calculate_transition(int* permatation) { bool* processed = new bool[n]; for (int i = 0; i < n; processed[i++] = false); int* inversed = new int[n]; for (int i = 0; i < n; inversed[permatation[i]] = i, i++); for (int i = 0; i < n; i++) { if (processed[i]) continue; if (permatation[i] == i) { processed[i] = true; continue; } if (permatation[permatation[i]] == i) { add_transition(first_transpoztion, i, permatation[i]); processed[permatation[i]] = true; processed[i] = true; continue; } int position_to_fix = i, where_is_right_person = inversed[i]; processed[where_is_right_person] = processed[position_to_fix] = true; while(true) { add_transition(second_transpoztion, position_to_fix, where_is_right_person); add_transition(first_transpoztion, position_to_fix, inversed[where_is_right_person]); // we want where_is_right_person to be inversed[where_is_right_person] where_is_right_person = inversed[where_is_right_person]; position_to_fix = permatation[position_to_fix]; processed[where_is_right_person] = processed[position_to_fix] = true; if (where_is_right_person == position_to_fix) { break; } if (permatation[position_to_fix] == where_is_right_person) { add_transition(second_transpoztion, position_to_fix, where_is_right_person); break; } } } } void print_transpozition(const std::vector<int>& trans) { std::cout << trans.size() << endl; for (int i = 0; i < trans.size(); i+=2) std::cout << (trans[i] + 1) << " "; for (int i = trans.size() - 1; i > 0; i -= 2) std::cout << (trans[i] + 1) << " "; std::cout << endl; } int main() { std::cin >> n; tab.reserve(n); int height; for (int i = 0; i < n; i++) { std::cin >> height; tab.push_back({ height, i }); } std::sort(tab.begin(), tab.end()); int *permatation = new int[n]; for (int i = 0; i < n; i++) { permatation[tab[i].second] = i; } calculate_transition(permatation); if (first_transpoztion.size() == 0) { std::cout << "0\n"; } else if (second_transpoztion.size() == 0) { std::cout << "1\n"; print_transpozition(first_transpoztion); } else { std::cout << "2\n"; print_transpozition(first_transpoztion); print_transpozition(second_transpoztion); } } |
English