题意:给出长度为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; }
poj 2299 Ultra-QuickSort (归并排序,逆序数)
原文地址:http://blog.csdn.net/acm_code/article/details/40682207