POJ2299-归并排序

/*转载请注明出处:乄心-小黄豆http://blog.csdn.net/wuxinxiaohuangdou*/

问:一串数字,经过最少多少次相邻两个数之间的交换可以得到 由小到大排序的数字串。

#include<stdio.h>
int a[500001],t[500001];
__int64 sum;
int n;
void merge(int l,int m,int r);
void merge_sort(int l,int r) //划分 与 递归
{
	int m;
	if(l<r)    //注意条件!  一直划分到 子串为一个整数 。
	{
		m=(l+r)/2;  //划分取中值.
		merge_sort(l,m);  //分为左部分  递归
		merge_sort(m+1,r);//分为右部分   递归 
		merge(l,m,r);// 调用归并排序函数.
	}
}
void merge(int l,int m,int r)
{
	int p=0;   //设置p指向 辅助数组空间.
	int i=l,j=m+1; //设置 i,j分别指向 两个子序列串的 头 。
	while(i<=m&&j<=r)  //比较到一个子序列比较完了为止.
	{
		if(a[i]>a[j])
		{
			t[p++]=a[j++]; //存储最小的 放到辅助数组.
			sum+=m-i+1; // 前部分的第一个数字(也就是这个子串的最小数字)大于 后部分字串的某一个数字(它)的话,前部分后面的都大于它.
		}
		else t[p++]=a[i++];  
	}
	while(i<=m) t[p++]=a[i++];//把剩下的存入辅助数组.
	while(j<=r) t[p++]=a[j++];
	for(i=0;i<p;i++)          //辅助数组 赋值回 原数组.
	{
		a[l+i]=t[i];
	}
}
int main()
{
	int i;
	while(1)
	{
		scanf("%d",&n);
		if(n==0) break;
		sum=0;
		for(i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
		}
		merge_sort(0,n-1);
		printf("%I64d\n",sum);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值