码迷,mamicode.com
首页 > 编程语言 > 详细

poj 2299 Ultra-QuickSort (归并排序,逆序数)

时间:2014-11-01 17:48:33      阅读:247      评论:0      收藏:0      [点我收藏+]

标签:poj   归并排序   

链接:poj 2299

题意:给出长度为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 (归并排序,逆序数)

标签:poj   归并排序   

原文地址:http://blog.csdn.net/acm_code/article/details/40682207

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!