#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); } } |