您的位置:首页 > 产品设计 > UI/UE

poj2299 Ultra-QuickSort

2014-05-11 18:22 204 查看
链接: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 0x7fffffff
int 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: