题意:给出长度为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;
}