zoukankan      html  css  js  c++  java
  • 【NOIP2013模拟联考5】休息(rest)

    Description
    休息的时候,可以放松放松浑身的肌肉,打扫打扫卫生,感觉很舒服。在某一天,某LMZ 开始整理他那书架。已知他的书有n 本,从左到右按顺序排列。他想把书从矮到高排好序,而每一本书都有一个独一无二的高度Hi。他排序的方法是:每一次将所有的书划分为尽量少的连续部分,使得每一部分的书的高度都是单调下降,然后将其中所有不少于2 本书的区间全部翻转。重复执行以上操作,最后使得书的高度全部单调上升。可是毕竟是休息时间,LMZ 不想花太多时间在给书排序这种事上面。因此他划分并翻转完第一次书之后,他想计算,他一共执行了多少次翻转操作才能把所有的书排好序。LMZ 惊奇地发现,第一次排序之前,他第一次划分出来的所有区间的长度都是偶数。

    Input
    第一行一个正整数n, 为书的总数。

    接下来一行n个数,第i个正整数Hi,为第i 本书的高度。

    Output
    仅一个整数,为LMZ 需要做的翻转操作的次数。

    Sample Input
    6

    5 3 2 1 6 4

    Sample Output
    3

    【样例解释】

    第一次划分之后,翻转(5,3,2,1),(6,4)。之后,书的高度为1 2 3 5 4 6,然后便是翻转(5,4)即可。

    Data Constraint
    对于10%的数据:n<=50
    对于40%的数据:n<=3000
    对于100%的数据:1<=n<=100000, 1<=Hi<=n
    .
    .
    .
    .
    .

    分析

    找出所有连续的单调下降序列,把它们全部翻转过来,每翻转一个序列,ans++,做完后,此为第一次交换。
    第一次交换后,剩下的就只能两两交换,所以只要求逆序对就好了。
    .
    .
    .
    .
    .

    程序:
    #include<iostream>
    #include<algorithm>
    using namespace std;
    long long a[100001],b[100001],n,w,t[100001],ans=0;
    
    void merge(long long a[],int l,int r)
    {
        if(l==r) return;
        int mid=(l+r)/2;
        merge(a,l,mid);
        merge(a,mid+1,r);
        int i=l,j=mid+1,p=l;
        while (i<=mid&&j<=r)
        {
            if (a[i]>a[j])
            {
                t[p++]=a[j++];
                ans+=mid-i+1;
            }
            else
            t[p++]=a[i++];
        }
        while(i<=mid) t[p++]=a[i++];
        while(j<=r) t[p++]=a[j++];
        for(i=l;i<=r;i++)
        a[i]=t[i];
    }
    
    
    void kp(int l,int r)
    {
        if (l>=r) return;
        int i=l,j=r,mid=a[(l+r)/2];
        do
        {
            while (a[i]<mid) i++;
            while (a[j]>mid) j--;
            if (i<=j)
            {
                swap(a[i],a[j]);
                i++;
                j--;
            }
        }while (i<=j);
    }
    
    int check()
    {
        for (int i=2;i<=n;i++)
        if (a[i]<a[i-1])
        {
            w=i;
            return 1;
        }
        return 0;
    }
    
    int main()
    {
        cin>>n;
        int tot=1;
        b[tot]=1;
        cin>>a[1];
        for (int i=2;i<=n;i++)
        {
            cin>>a[i];
            if (a[i]>a[i-1])
            {
                tot++;
                b[tot]=i;
            }
        }
        tot++;
        b[tot]=n;
        for (int i=2;i<=tot;i++)
        {
            kp(b[i-1],b[i]);
            ans++;
        }
        merge(a,1,n);
        cout<<ans;
    }
  • 相关阅读:
    LeetCode 275. H-Index II
    LeetCode 274. H-Index
    LeetCode Gray Code
    LeetCode 260. Single Number III
    LeetCode Word Pattern
    LeetCode Nim Game
    LeetCode 128. Longest Consecutive Sequence
    LeetCode 208. Implement Trie (Prefix Tree)
    LeetCode 130. Surrounded Regions
    LeetCode 200. Number of Islands
  • 原文地址:https://www.cnblogs.com/YYC-0304/p/9499917.html
Copyright © 2011-2022 走看看