題意:給出長度爲n的序列,每次只能交換相鄰的兩個元素,
問至少要交換幾次才使得該序列爲遞增序列
分析:冒泡排序每次只能交換相鄰兩個元素,也就是求
用冒泡排序使其爲遞增序列的交換次數,每交換一次記錄一次就好
但是這題數據較大,冒泡排序效率比較低,會超時的
這裏就可以利用歸併排序了,用歸併排序可以求序列的逆序數,
而一個序列的 逆序數 = 只允許相鄰兩個元素交換時,得到有序序列的交換次數
#include<stdio.h>
#include<stdlib.h>
#define M 500000
int a[M+5],l[M+5],r[M+5];
__int64 t;
void cmp(int ll,int mid,int rr)
{
int m=0,n=0,i,j,k;
for(i=ll;i<=mid;i++)
l[m++]=a[i];
for(i=mid+1;i<=rr;i++)
r[n++]=a[i];
i=j=0;
k=ll;
while(i<m&&j<n){
if(l[i]<=r[j])
a[k++]=l[i++];
else{
a[k++]=r[j++];
t+=m-i; //計算逆序數
}
}
while(i<m)
a[k++]=l[i++];
while(j<n)
a[k++]=r[j++];
}
void mergesort(int l,int r)
{
int mid;
if(l<r){
mid=(l+r)/2;
mergesort(l,mid);
mergesort(mid+1,r);
cmp(l,mid,r);
}
}
int main()
{
int n,i;
while(scanf("%d",&n)&&n){
for(i=0;i<n;i++)
scanf("%d",&a[i]);
t=0;
mergesort(0,n-1);
printf("%I64d\n",t);
}
return 0;
}