#include <cstdio> #include <vector> #include <algorithm> #include <utility> static std::vector<int> load_data() { int n; scanf("%d", &n); std::vector<int> data; data.reserve(n); for (int i = 0; i < n; i++) { int x; scanf("%d", &x); data.push_back(x); } return data; } static void convert_to_permutation(std::vector<int>& data) { std::vector<int> reverse_perm; reverse_perm.reserve(data.size()); for (int i = 0; i < data.size(); i++) { reverse_perm.push_back(i); } std::sort(reverse_perm.begin(), reverse_perm.end(), [&] (int a, int b) { return data[a] < data[b]; }); for (int i = 0; i < data.size(); i++) { data[reverse_perm[i]] = i; } } static std::vector<std::vector<int>> unwrap_cycles(std::vector<int> data) { std::vector<std::vector<int>> ret; for (int i = 0; i < data.size(); i++) { if (data[i] == -1) { continue; // Already visited } if (data[i] == i) { continue; // Ignore 1-cycles } std::vector<int> cycle; int curr = i; while (data[curr] != -1) { cycle.push_back(curr); curr = std::exchange(data[curr], -1); }; ret.push_back(std::move(cycle)); } return ret; } static void command_to_swap_cycles(const std::vector<std::vector<int>>& unwrapped, int beginning_skip_count) { std::vector<int> left, right; for (const auto& cyc : unwrapped) { const int adjusted_len = cyc.size() - beginning_skip_count; if (adjusted_len <= 1) { continue; } for (int i = 0; i < adjusted_len / 2; i++) { left.push_back(cyc[beginning_skip_count + i]); right.push_back(cyc[cyc.size() - 1 - i]); } } printf("%d\n", (int)(left.size() + right.size())); for (int i = 0; i < left.size(); i++) { printf("%d ", left[i] + 1); } for (int i = right.size() - 1; i >= 0; i--) { printf("%d ", right[i] + 1); } putchar('\n'); } int main() { auto data = load_data(); convert_to_permutation(data); auto unwrapped = unwrap_cycles(std::move(data)); if (unwrapped.empty()) { // It is already sorted puts("0"); return 0; } bool has_long_cycles = false; for (const auto& cyc : unwrapped) { if (cyc.size() > 2) { has_long_cycles = true; break; } } printf("%d\n", has_long_cycles ? 2 : 1); command_to_swap_cycles(unwrapped, 0); if (has_long_cycles > 0) { command_to_swap_cycles(unwrapped, 1); } return 0; }
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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | #include <cstdio> #include <vector> #include <algorithm> #include <utility> static std::vector<int> load_data() { int n; scanf("%d", &n); std::vector<int> data; data.reserve(n); for (int i = 0; i < n; i++) { int x; scanf("%d", &x); data.push_back(x); } return data; } static void convert_to_permutation(std::vector<int>& data) { std::vector<int> reverse_perm; reverse_perm.reserve(data.size()); for (int i = 0; i < data.size(); i++) { reverse_perm.push_back(i); } std::sort(reverse_perm.begin(), reverse_perm.end(), [&] (int a, int b) { return data[a] < data[b]; }); for (int i = 0; i < data.size(); i++) { data[reverse_perm[i]] = i; } } static std::vector<std::vector<int>> unwrap_cycles(std::vector<int> data) { std::vector<std::vector<int>> ret; for (int i = 0; i < data.size(); i++) { if (data[i] == -1) { continue; // Already visited } if (data[i] == i) { continue; // Ignore 1-cycles } std::vector<int> cycle; int curr = i; while (data[curr] != -1) { cycle.push_back(curr); curr = std::exchange(data[curr], -1); }; ret.push_back(std::move(cycle)); } return ret; } static void command_to_swap_cycles(const std::vector<std::vector<int>>& unwrapped, int beginning_skip_count) { std::vector<int> left, right; for (const auto& cyc : unwrapped) { const int adjusted_len = cyc.size() - beginning_skip_count; if (adjusted_len <= 1) { continue; } for (int i = 0; i < adjusted_len / 2; i++) { left.push_back(cyc[beginning_skip_count + i]); right.push_back(cyc[cyc.size() - 1 - i]); } } printf("%d\n", (int)(left.size() + right.size())); for (int i = 0; i < left.size(); i++) { printf("%d ", left[i] + 1); } for (int i = right.size() - 1; i >= 0; i--) { printf("%d ", right[i] + 1); } putchar('\n'); } int main() { auto data = load_data(); convert_to_permutation(data); auto unwrapped = unwrap_cycles(std::move(data)); if (unwrapped.empty()) { // It is already sorted puts("0"); return 0; } bool has_long_cycles = false; for (const auto& cyc : unwrapped) { if (cyc.size() > 2) { has_long_cycles = true; break; } } printf("%d\n", has_long_cycles ? 2 : 1); command_to_swap_cycles(unwrapped, 0); if (has_long_cycles > 0) { command_to_swap_cycles(unwrapped, 1); } return 0; } |