zoukankan      html  css  js  c++  java
  • UVA

    题目:

    输入一个1~n(1≤n≤300)的排列,用不超过96次操作把它变成升序。每次操作都可以选一个长度为偶数的连续区间,交换前一半和后一半。输出每次操作选择的区间的第一个和最后一个元素。

    思路:

    注意紫书上的提示,2n次操作就可以完成了。从头开始遍历序列,属于该位置上的元素,可以在两步之内交换到这里。

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define MAX 1e3
    #define FRE() freopen("in.txt","r",stdin)
    #define FRO() freopen("out.txt","w",stdout)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> P;
    const int maxn = 10010;
    vector<P> ans;
    int a[maxn], pos[maxn];
    int n;
    
    void toSwap(int l, int r) {//完成区间前半段和后半段的交换
        int mid = (l + r) / 2;
        for(int i = 0; l + i <= mid; i++) {
            swap(a[l + i], a[mid + i + 1]);
            swap(pos[a[l+i]], pos[a[mid+i+1]]);//记得位置也要跟着交换过来
        }
        ans.push_back(P(l, r));
    }
    
    int main() {
        //FRE();
        int kase;
        scanf("%d", &kase);
        while(kase--) {
            ans.clear();
            memset(a, 0, sizeof(a));
            memset(pos, 0, sizeof(pos));
            scanf("%d", &n);
            for(int i = 1; i <= n; i++) {
                scanf("%d", &a[i]);
                pos[a[i]] = i;
            }
    
            for(int i = 1; i <= n; i++) {
                //cout<<"GG"<<endl;
                if(a[i] == i) {
                    continue;
                }
                int idx = pos[i];
                while(a[i] != i) {
                    if(n - idx + 1 >= idx - i) {//如果idx到n的距离大于等于区间[i,idx]的长度
                        toSwap(i, i + (idx - i) * 2 - 1);
                    } else {//否则就先将元素往前交换移动
                        int len = idx - i + 1;
                        if(len % 2 == 1) {
                            toSwap(i+1,idx);
                        }else{
                            toSwap(i, idx);
                        }
                        idx -= len/2;
                    }
                }
            }
            printf("%d
    ",ans.size());
            for(int i=0; i<ans.size(); i++){
                printf("%d %d
    ",ans[i].first,ans[i].second);
            }
        }
        return 0;
    }
  • 相关阅读:
    深入理解C++的动态绑定和静态绑定
    【转载】“惊群”,看看nginx是怎么解决它的
    352. Data Stream as Disjoint Intervals
    lambda
    auto
    sizeof(类)
    private是自己私有的,protected是可以让孩子知道的,public是公开的
    【转载】C++ typedef用法小结
    string char * const char *之间的互相转换
    【转载】Web Service 的工作原理
  • 原文地址:https://www.cnblogs.com/sykline/p/10347621.html
Copyright © 2011-2022 走看看