是不是很像摊煎饼那道例题,唯一的区别是这次是从中间开始交换左右两边的元素,而两边各自元素的顺序不变。
因此尝试每次将一个元素摆到正确的位置。尝试后发现,(稍微分奇偶讨论下)每个元素最多用两次就可以归位,所以复杂度最坏情况下是O(2n)
像其他需要交换元素位置的题目一样,这道题也需要注意一下边界。另外起始位置是0还是1也要小心。其他的就没有特别的了
Run Time: 0.768s
#define UVa "8-6.1611.cpp" //Crane
char fileIn[30] = UVa, fileOut[30] = UVa;
#include<cstring>
#include<cstdio>
#include<vector>
#include<ctime>
using namespace std;
//Global Variables. Reset upon Each Case!
const int maxn = 10000 + 10;
const int lim = 531441;
int T, n, A[maxn], P[maxn];
vector<int> ans[2];
int anscnt;
/
void swp(int* a, int l, int r) {
int tmp[maxn];
for(int i = 0; i < (r+1-l)/2; i ++) {
int &a1 = a[l + i], &a2 = a[l + i + (r+1-l)/2];
swap(a1, a2);
swap(P[a1-1], P[a2-1]);
}
}
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = 0; i < n ; i ++) {
scanf("%d", &A[i]);
P[A[i]-1] = i;
}
anscnt = 0;
ans[0].clear();
ans[1].clear();
for(int i = 0; i < n; i ++) {
int p = P[i];
if(i != p) {
if(2*p-i-1 < n) {
swp(A, i, 2*p-i-1);
ans[0].push_back(i);
ans[1].push_back(2*p-i-1);
anscnt ++;
}
else {
if((p-i)%2 == 1) {
swp(A, i+2, p);
swp(A, i, p);
ans[0].push_back(i+2);
ans[1].push_back(p);
ans[0].push_back(i);
ans[1].push_back(p);
anscnt += 2;
}
else {
swp(A, i+1, p);
swp(A, i, p-1);
ans[0].push_back(i+1);
ans[1].push_back(p);
ans[0].push_back(i);
ans[1].push_back(p-1);
anscnt += 2;
}
}
}
}
printf("%d\n", anscnt);
for(int i = 0; i < ans[0].size(); i ++) {
printf("%d %d\n", ans[0][i]+1, ans[1][i]+1);
}
}
return 0;
}