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

求逆序对——Ultra-QuickSort 题解解析

2015-07-29 20:32 316 查看
Description

Inthisproblem,youhavetoanalyzeaparticularsortingalgorithm.Thealgorithmprocessesasequenceofndistinctintegersbyswappingtwoadjacentsequenceelementsuntilthesequenceissortedinascendingorder.Fortheinputsequence

91054,

Ultra-QuickSortproducestheoutput

01459.

YourtaskistodeterminehowmanyswapoperationsUltra-QuickSortneedstoperforminordertosortagiveninputsequence.



Input

Theinputcontainsseveraltestcases.Everytestcasebeginswithalinethatcontainsasingleintegern<500,000--thelengthoftheinputsequence.Eachofthethefollowingnlinescontainsasingleinteger0≤a[i]≤999,999,999,
thei-thinputsequenceelement.Inputisterminatedbyasequenceoflengthn=0.Thissequencemustnotbeprocessed.

Output

Foreveryinputsequence,yourprogramprintsasinglelinecontaininganintegernumberop,theminimumnumberofswapoperationsnecessarytosortthegiveninputsequence

SampleInput

5

91054

3123
0


SampleOutput

6
0

求逆序对的问题可以用冒泡排序,但是当序列够长的时候,冒泡排序的复杂度是不能满足要求的。我们可以用归并排序的思路求解。

代码如下:



#include<iostream>
#include<sstream>
#include<ios>
#include<iomanip>
#include<functional>
#include<algorithm>
#include<vector>
#include<string>
#include<list>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<climits>
#include<cctype>
usingnamespacestd;
#defineXINFINT_MAX
#defineINF0x3F3F3F3F
#defineMP(X,Y)make_pair(X,Y)
#definePB(X)push_back(X)
#defineREP(X,N)for(intX=0;X<N;X++)
#defineREP2(X,L,R)for(intX=L;X<=R;X++)
#defineDEP(X,R,L)for(intX=R;X>=L;X--)
#defineCLR(A,X)memset(A,X,sizeof(A))
#defineITiterator
typedeflonglongll;
typedefpair<int,int>PII;
typedefvector<PII>VII;
typedefvector<int>VI;
//constintMAXN=10010;
//#defineINF0x3FFFFFFF
/*************************************
**************头文件*****************
*************************************/
lla[500005],b[500005];
llans;
voidMerge(lla[],lllow,llmid,llhigh)
{
// ll*b=newll[high+1];/////不能动态分配内存,会TME
lli=low,j=mid+1,k=low;
while(i<=mid&&j<=high)
if(a[i]<=a[j])
b[k++]=a[i++];
else
{
b[k++]=a[j++];
ans+=mid+1-i; //这里将a[j]赋给b[k]中间跳过了mid+1-i个数
} //这些数就是a[j]共有多少个逆序对
while(i<=mid)
b[k++]=a[i++];
while(j<=high)
b[k++]=a[j++];
for(i=low;i<=high;i++)
a[i]=b[i];
}
voidMergeSort(lla[],lln)//两路归并
{
lllen=1,i;
while(len<n){
i=0;
while(i+2*len<=n){
Merge(a,i,i+len-1,i+2*len-1);
i+=2*len;
}
if(i+len<n)
Merge(a,i,i+len-1,n-1);
len*=2;
}
}
intmain()
{
lln;
while(cin>>n&&n)
{
REP(i,n)
cin>>a[i];
ans=0;
MergeSort(a,n); //调用归并函数进行排序
cout<<ans<<endl; //直接输出答案
}
return0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: