从左到右,依次把一个个数放到位。把一个数放到正确的位置,观察发现最多两步
假设操作到第i个位置,而i这个数刚好在pos这个位置上,现在就要判断一下能否直接将pos上的i经过操作调到i这个位置上
如果 i + (pos - i) * 2 - 1 <= n,表示可以一次操作完成
在上面条件不成立的情况下,又分为两种情况
一种是pos和i的距离是奇数的情况:那么就直接将[i,pos]这个区间的值进行交换即可
另一种是距离为偶数的情况,那就把[i+1,pos]这个区间的值进行交换即可
AC代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cctype> #include <cstring> #include <string> #include <sstream> #include <vector> #include <set> #include <map> #include <algorithm> #include <stack> #include <queue> #include <bitset> #include <cassert> #include <cmath> #include <functional> using namespace std; const int maxn = 10005; int numbers[maxn]; void exchange(int L, int R) { for (int i = L, j = L + (R - L + 1) / 2; j <= R; j++, i++) { swap(numbers[i], numbers[j]); } } int main() { ios::sync_with_stdio(false); int T; cin >> T; while (T--) { int n; cin >> n; for (int i = 1; i <= n; i++) { cin >> numbers[i]; } vector<pair<int, int> > ans; for (int i = 1; i <= n; i++) { int pos; for (int j = i; j <= n; j++) { if (numbers[j] == i) { // 找到i的位置 pos = j; break; } } if (pos == i) { continue; } if (i + 2 * (pos - i) - 1 <= n) { // 满足这个条件可直接 ans.push_back(make_pair(i, i + 2 * (pos - i) - 1)); exchange(i, i + 2 * (pos - i) - 1); } else { if ((pos - i) % 2) { ans.push_back(make_pair(i, pos)); exchange(i, pos); } else { ans.push_back(make_pair(i + 1, pos)); exchange(i + 1, pos); } i--; } } cout << ans.size() << endl; for (int i = 0; i < ans.size(); i++) { cout << ans[i].first << ' ' << ans[i].second << endl; } } return 0; }
原文地址:http://blog.csdn.net/zyq522376829/article/details/46613363