题目:题目链接
思路:思路+构造,假设 i 在pos 位置,那么如果 (pos-i-1)*2+i+1 <= n,那么可以操作一次换过来,如果他们之间元素个数是偶数,那么交换 i - pos,如果是奇数,交换 i - pos+1,然后再经过一次就可以换到指定位置,如果是奇数并且pos==n,先与前一个元素交换一下,然后执行前面的操作。
AC代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <set> #include <map> #include <unordered_set> #include <unordered_map> #include <queue> #define INF 0x3f3f3f3f #define FRER() freopen("in.txt", "r", stdin); #define FREW() freopen("out.txt", "w", stdout); using namespace std; const int maxn = 10000 + 5; int n, num[maxn], pos[maxn]; typedef pair<int, int> P; void Swap(int l, int m) { for(int i = 0; i < m; ++i) { swap(num[l + i], num[l + i + m]); pos[num[l + i]] = l + i; pos[num[l + i + m]] = l + i + m; } } int main() { ios::sync_with_stdio(0); cin.tie(0); int T; cin >> T; while(T--) { cin >> n; for(int i = 1; i <= n; ++i) { cin >> num[i]; pos[num[i]] = i; } vector<P> vec; for(int i = 1; i <= n; ++i) { if(num[i] == i) continue; int temp = pos[i] - i - 1; if(temp * 2 + i + 1 <= n) { vec.push_back(make_pair(i, pos[i] + temp)); Swap(i, temp + 1); ++i; } else if(temp % 2 == 0) { vec.push_back(make_pair(i, pos[i])); Swap(i, temp / 2 + 1); } else if(pos[i] == n) { vec.push_back(make_pair(n - 1, n)); Swap(n - 1, 1); } else { vec.push_back(make_pair(i, pos[i] + 1)); Swap(i, temp / 2 + 2); } --i; } cout << vec.size() << endl; for(int i = 0; i < vec.size(); ++i) cout << vec[i].first << ' ' << vec[i].second << endl; } return 0; }