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

HDU 3743 (归并排序模板题)

时间:2015-08-07 22:05:23      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:

题意:给定一个序列,然后将此序列按升序排列,每次操作只能交换相邻的两个数,求达到目标所需的最小交换次数;(ps:此题需用 long long ,否则会wa)

当然这其实就是求逆序对数;

归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define maxn 10000010
int ac[maxn],temp[maxn];
long long ans;
void merger(int *A,int s,int mid,int e)
{
    int i,j,k=0;;
    for(i=s,j=mid+1;i<=mid && j<=e;)
    {
        if(A[i] < A[j])
             temp[k++]=A[i++];
        else
        {
            ans+= mid-i+1;//当a[i] > a[j]时,说明a[j]比前面那段啊[i],a[i+1],a[i+2]....,a[mid],比这些都要小,所以总逆序对数要加上mid-i+1.
            temp[k++]=A[j++];
        }

    }
    while(i<=mid) temp[k++]=A[i++];
    while(j<=e) temp[k++]=A[j++];
    for(i=0;i<k;i++)
        A[s+i]=temp[i];
}
void mergersort(int *A,int s,int e)
{
    if(s<e)
    {
        int mid=(s+e)/2;
        mergersort(A,s,mid); 
        mergersort(A,mid+1,e);
        merger(A,s,mid,e);
    }
}
int main()
{
    int i,n;
    while(~scanf("%d",&n))
    {
        for(i=0; i<n; i++)
            scanf("%d",&ac[i]);
        ans=0;
        mergersort(ac,0,n-1);
        printf("%lld\n",ans);
    }
    return 0;
}

  

HDU 3743 (归并排序模板题)

标签:

原文地址:http://www.cnblogs.com/cn-blog-cn/p/4711858.html

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