Question Link
Question:
For a sequence, you can select an even length segment, then cut in the middle, and exchange the Left and Right segments. Here is a 1 ~ A certain arrangement of N, find an exchange scheme, and make the arrangement finally orderly. (Number of exchanges <9 ^ 6)
Ideas:
From left to right, place the numbers one by one in bits. Place a number in the correct position and observe that there are at most two steps. Number of I. If the current position is in [I + 1, (n + I)/2], it can be in place at one time. If it is on the right side, it can be passed once to make it within this range.
Code:
#include <cstdio>#include <cstring>#include <cstdlib>#include <cassert>#include <algorithm>using namespace std;#define N 10100int a[N];int id[N];int n;struct Ans{ int l, r; Ans(int _l=0, int _r =0) : l(_l), r(_r){}}ans[2*N];int ap;void myswap(int l, int r) { ans[ap++] = Ans(l,r); //printf("l = %d, r = %d\n", l, r); assert((r-l+1)%2 == 0); int mid = (l+r)/2; int lp = l; int rp = mid+1; while (lp <= mid) { swap(id[a[lp]], id[a[rp]]); swap(a[lp], a[rp]); lp++; rp++; } //puts("after---"); //for (int i = 0; i < n; i++) { // printf("%d ", a[i]+1); //}puts("");}int main() { int t; scanf("%d", &t); while (t--) { scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &a[i]); a[i]--; } for (int i = 0; i < n; i++) { id[a[i]] = i; } ap = 0; for (int i = 0; i < n; i++) { if (id[i] == i) continue; int flag = (n+i)/2; if (id[i] > flag) { myswap( flag - (id[i]-flag-1) ,id[i] ); } //printf("i = %d, swap(%d->%d)\n", i, i, id[i]+(id[i]-i-1)); myswap(i, id[i] + (id[i]-i-1)); } //for (int i = 0; i < n; i++) { // printf("%d ", a[i]); //}puts(""); printf("%d\n", ap); for (int i = 0; i < ap; i++) { printf("%d %d\n", ans[i].l+1, ans[i].r+1); } } return 0;}
Va 1611: crane (build grade D)