poj2299 Ultra-QuickSort

来源:互联网 发布:单片机论坛网 编辑:程序博客网 时间:2024/05/22 17:30

链接:http://poj.org/problem?id=2299

题意:有一个序列,求在只能相邻两数交换位置的情况下,交换几次使得其升序排列。

额,我看时间7000MS,,一开始我就用冒泡了。。。TLE。

应该用归并排序做,用的是求逆序对个数的方法。

【逆序对的个数=当且仅当数组a[]按紧邻两数才交换的方式(类似按冒泡排序的方式)排成有序序列所需的交换次数】

一开始抄了数据结构书上的一个归并排序的模板,尼玛,RE了N次。。。是书上的那个程序有问题吗?

这个题的输出要用__int64.之前一直在针对这一点,改成long long,改成“%lld”,"%l64d".,以为RE是这里的原因。其实不是的。

然后网上抄了一个,过了。还是贴一下代码吧,也是一个不错的归并排序的模板。


#include<stdlib.h>#include<stdio.h>#define MAXN 500105#define INF 0x7fffffffint a[MAXN],l[MAXN],r[MAXN];__int64 ans;void Merge(int low,int high){int n1,n2,i,j,k;    n1=(high+low)/2-low+1;n2=high-(high+low)/2;  //n2=high-((high+low)/2+1)+1    for(i=1;i<=n1;i++)l[i]=a[low+i-1];for(j=1;j<=n2;j++)r[j]=a[(high+low)/2+j];l[n1+1]=INF;   //设置哨兵,防止越界r[n2+1]=INF;i=j=1;for(k=low;k<=high;k++)if(l[i]<=r[j])a[k]=l[i++];else{    a[k]=r[j++];ans+=n1-i+1;//逆序对数,因为l[i..n1]有序,l[i]>r[j],则l[i+1..n1]均大于r[j]}}void MSort(int low,int high){    if(low<high)    {        int mid=(low+high)/2;        MSort(low,mid);        MSort(mid+1,high);        Merge(low,high);    }}void MergeSort(int n){    MSort(1,n);}int main(){    int n,i;    while(scanf("%d",&n)!=EOF)    {        if(!n)return 0;        for(i=1;i<=n;i++)            scanf("%d",&a[i]);        ans=0;        MergeSort(n);        printf("%lld\n",ans);    }    return 0;}


0 0
原创粉丝点击