zoukankan      html  css  js  c++  java
  • Ultra-QuickSort——[归并排序、分治求逆序对]

    Description

      In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence 
    9 1 0 5 4 ,

    Ultra-QuickSort produces the output 
    0 1 4 5 9 .

      Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

    Input

      The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.

    Output

      For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

    Sample Input

    5
    9
    1
    0
    5
    4
    3
    1
    2
    3
    0
    

    Sample Output

    6
    0
    解题思路:
      本题揭示了排序的本质——消除逆序对。逆序对,是指对于满足 当i<j时,a[i]>a[j]的序偶(a[i],a[j])。可以证明,交换序列中任意两个
    相邻元素,逆序对增加或减少一。那么对于一个给定的序列,按一次交换一对相邻元素的方法,最少需要要交换的次数等于此序列中逆序对的数目
    那么问题就变成了如何求给定序列的逆序对。可以采用分治的方法:
      整个序列逆序对数=左半序列逆序对数+右半序列逆序对数+前一个元素在左半序列,后一个元素在右半序列的逆序对数。
      再细考虑可以发现,这个过程可以在归并排序的同时完成,时间复杂度为O(NlogN).

    注意
    :可以简单计算一下,n个元素的排列逆序对数最多有 n(n-1)/2个,需要用到long long。

    代码如下:
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <ctime>
     5 using namespace std;
     6 #define print_time_ printf("time : %f
    ",double(clock())/CLOCKS_PER_SEC)
     7 #define maxn 500000
     8 int A[maxn+5];
     9 
    10 typedef long long LL;
    11 LL DC(int a,int N){
    12     int mid=a+N/2-1;
    13     int b=a+N-1;
    14     if(N==1)
    15         return 0;
    16     
    17     LL x1=DC(a, N/2);
    18     LL x2=DC(mid+1,b-mid);
    19     LL x3=0;
    20     int *B=new int[N];
    21     int i=a,j=mid+1,p=0;
    22     for(;i<=mid&&j<=b&&p<N;p++){
    23         if(A[i]<=A[j]){
    24             B[p]=A[i++];
    25         }
    26         else {
    27             B[p]=A[j++];
    28             x3+=mid-i+1;
    29         }
    30     }
    31     while(i<=mid){B[p++]=A[i++];}
    32     while(j<=b){B[p++]=A[j++];}
    33     memcpy(A+a, B, N*sizeof(int));
    34     delete [] B;
    35     return x1+x2+x3;
    36 }
    37 int main() {
    38     int n;
    39     while(scanf("%d",&n)==1&&n){
    40         for(int i=0;i<n;i++)
    41             scanf("%d",&A[i]);
    42         printf("%lld
    ",DC(0, n));
    43     }
    44     //print_time_;
    45     return 0;
    46 }
    
    
    


  • 相关阅读:
    react中使用map时onClick事件失效
    【Taro全实践】Taro在微信小程序中的生命周期
    git的基本操作
    【Taro全实践】修改radio组件的大小
    react中回车enter事件处理
    安装nodejs 后运行 npm 命令无响应
    React中跨域问题的完美解决方案
    在React中修改antd的样式
    Linux 开机过程(转)
    Microsoft Windows XP Professional X64 Edition Corporate Keys
  • 原文地址:https://www.cnblogs.com/Kiraa/p/5304420.html
Copyright © 2011-2022 走看看