Crane UVA

题目:题目链接

思路:思路+构造,假设 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;
}
原文地址:https://www.cnblogs.com/fan-jiaming/p/10004657.html