pku2299: Ultra-QuickSort

pku2299:http://poj.org/problem?id=2299
题意:给出n个数,问要将其按从小到大排序至少需要多少步骤。
解法:归并排序:将待排序集合一分为二,直至待排序集合只剩下一个元素为止,然后不断合并两个排好序的数组段。
code:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int d[500005],c[500005];
__int64 ans;
void msort(int l,int m,int r)
{
    int i=l,j=m+1,k=0;
    while(i<=m&&j<=r)     
    {
        if(c[i]<=c[j])        //若左子树的i已小于右子树的j,直接将i放入新数组
            d[k++]=c[i++];
        else                 //若i>j,要将j放入新数组,需要调换i与j的位置,调换步骤数为j与i之间个数加一,由于每次操作都会取出某个数(i或j,较小的数),所以步骤数为m-i+1
        {
            d[k++]=c[j++];
            ans+=m-i+1;
        }
    }
    if(i>m)                 //将剩下的数继续存入新数组
        for(int t=j;t<=r;t++)
            d[k++]=c[t];
    else
        for(int t=i;t<=m;t++)
            d[k++]=c[t];
    for(int j=0;j<k;j++)       //将改变后的数组d复制到c中
        c[l+j]=d[j];
}
void mergesort(int l,int r)      //递归将集合一分为二
{
    if(l<r)
    {
        int mid=(l+r)/2;
        mergesort(l,mid);
        mergesort(mid+1,r);
        msort(l,mid,r);
    }
}
int main()
{
    int n;
    while(1)
    {
        scanf("%d",&n);
        if(n==0)break;
        for(int i=0;i<n;i++)
            scanf("%d",&c[i]);
        ans=0;
        mergesort(0,n-1);
        printf("%I64d\n",ans);
    }
}
/*input:
5
9
1
0
5
4
3
1
2
3
0
output:
6
0*/

posted on 2012-08-01 23:11  acmer-jun  阅读(225)  评论(0编辑  收藏  举报

导航