超级快排:Ultra-QuickSort

超级快排:Ultra-QuickSort

总时间限制: 

7000ms

内存限制: 

65536kB

描述

在这个问题中,你需要分析特别的算法。这个算法通过对一个包含n个元素的进行操作,一直交换相邻的两个序列的元素直到整个序列呈升序排列。对于输入序列9 1 0 5 4 ,Ultra-QuickSort最终得到的输出为0 1 4 5 9 .你的任务就是来计算出Ultra-QuickSort 至少需要多少swap操作来最终达到对一个给定的输入序列排好序的目标。

输入

输入包括多组测试数据。每组测试数据以一行包括一个单独的整数n开始(n<500,000,是输入序列的长度)。每组测试数据接下来的n行包括一个单独的整数a[i],a[i]≤ 999,999,999,代表输入序列第n个元素。输入以一个长度n为0的序列终止。这个序列不应该被处理。

输出

对于每组测试数据,你的程序应该输入单独的一行,包括一个整数op,代表对该输入序列进行排序所需要最小的交换次数。

样例输入

5
9
1
0
5
4
3
1
2
3
0

样例输出

6
0

思路:

最开始:

  刚开始看到这道题的时候,我就觉得很简单啊,不就是求逆序对吗,于是,我写了一个特殊的bubble(就是冒泡排序,因为要计数,所以不能用STL库里面的sort),果然,超时了!(因为超时过于严重,所以就不发图片了)

中间:

  因为冒泡排序都已经严重超时了,我就想到了快速排序,因为STL库中的qsort快速排序函数不符合题目要求,就只能自己手写一个,我一下就码出来了:

#include
using namespace std;
int n,a[20005],tmp[20005];
int sum; 
inline void swap(int x,int y) {
    int tmp=a[x];
    a[x]=a[y];
    a[y]=tmp;
}
void qsort(int l,int r){
    if(l>=r) return;
    int mid=(l+r)/2;
    qsort(l,mid);
    qsort(mid+1,r);
    int p1=l,p2=mid+1,i=l;
    while(p1<=mid&&p2<=r){
        if(a[p1]<=a[p2])
          tmp[i++]=a[p1++];
        else if(a[p2]

  经过提交之后,emm……(又超时了)

超级快排:Ultra-QuickSort_第1张图片 

   都已经用了快速排序了,竟然还会超时?于是我决定用归并排序和桶排序了。

  我决定先用归并排序(因为我那时候还没有想好怎样用桶排序),在归并排序的函数中,没执行一次判断,就将ans(计数的)进行加(j-k)。

归并排序代码:

#include
const int MAXN=500010;
int a[MAXN],b[MAXN];
long long ans;
void mergesort(int start,int mid,int end){
    int i=start,k=start,j=mid+1;
    while(i<=mid&&j<=end){
        if(a[i]<=a[j])b[k++]=a[i++];
        else{
            ans+=j-k;
            b[k++]=a[j++];
        }
    }
        while(i<=mid)b[k++]=a[i++];
        while(j<=end)b[k++]=a[j++];
        for(int i=start;i<=end;i++)a[i]=b[i];
}
void ms(int l,int r){
    if(l

  经过这次归并排序后,提交以后我终于AC了。 

  这就是今天的排序题目,大家再见!

题目链接:

OpenJudge - 7:Ultra-QuickSorthttp://dsalgo.openjudge.cn/sort/7/超级快排:Ultra-QuickSort_第2张图片

你可能感兴趣的:(算法,数据结构,算法,C++,归并排序,快速排序,冒泡排序)