我是靠谱客的博主 失眠火车,最近开发中收集的这篇文章主要介绍超级快排: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<bits/stdc++.h>
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]<a[p1]){
            tmp[i++]=a[p2++];
            sum+=mid-p1+1;
        }
    }
    while(p2<=r)
      tmp[i++]=a[p2++];
    while(p1<=mid)
      tmp[i++]=a[p1++];
    for(int i=l;i<=r;i++) a[i]=tmp[i];
} 
void init(){
    while(scanf("%d",&n)!=EOF&&n){
        sum=0;
        for(int i=1;i<=n;i++)
          scanf("%d",&a[i]);
        qsort(1,n);
        printf("%dn",sum);
    }
}
int main(){
    init();
    return 0;
}

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

 

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

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

归并排序代码:

#include<stdio.h>
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<r){
        int mid=(l+r)/2;
        ms(l,mid);
        ms(mid+1,r);
        mergesort(l,mid,r);
    }
}
int main(){
    int n;
    while(scanf("%d",&n),n){
        ans=0;
        for(int i=1;i<=n;i++)scanf("%d",a+i);
        ms(1,n);
        printf("%lldn",ans);
    }
    return 0;
}

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

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

题目链接:

OpenJudge - 7:Ultra-QuickSorthttp://dsalgo.openjudge.cn/sort/7/

最后

以上就是失眠火车为你收集整理的超级快排:Ultra-QuickSort思路:归并排序代码:的全部内容,希望文章能够帮你解决超级快排:Ultra-QuickSort思路:归并排序代码:所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部