Brainman POJ - 1804 归并排序求逆序对数

17 篇文章 0 订阅

Brainman POJ - 1804 归并排序求逆序对数

在这里插入图片描述
原理:可以用归并排序计算逆序对数,在归并排序中的交换次数就是这个序
列的逆序对数:归并排序是将序列a[l, r]分成两个序列a[l, mid]和a[mid

  • 1, r],分别进行归并排序,然后再将这两个有序序列进行归并排序,
    在归并排序的过程中,设l<=i<=mid,mid+1<=j<=r,当a[i]<=a[j]时,并不产生逆序对数;而当a[i]> a[j]时,则在有序序列a[l, mid]中,在a[i]后面的数
    都比a[j]大,将a[j]放在a[i]前,逆序对数就要加上mid-i+1。
#include<iostream>
using namespace std;

int ans;

void merge(int * s,int *temp,int l,int mid,int r)
{
	int a=l;
	int b=mid+1;
	int k=0;
	while(a<=mid && b<=r)
	{
		if(s[a]<=s[b])
		temp[k++]=s[a++];
		else 
		{
			ans+=(mid-a+1); 
			temp[k++]=s[b++];
		}
	}
	while(a<=mid)
		temp[k++]=s[a++];
	while(b<=r)
		temp[k++]=s[b++];
		
		
	int begin=l;
	for(int i=0;i<k;i++)
	{
		s[begin++]=temp[i];
	}
}

void mergeSort(int * s,int * temp,int l,int r)
{
	if(l==r)
	return ;
	
	int mid=(l+r)/2;
	
	mergeSort(s,temp,l,mid);
	mergeSort(s,temp,mid+1,r);
	merge(s,temp,l,mid,r); 
}


int cases,n;
int main()
{
	int s[1005];
	int temp[1005];
	
	cin>>cases;
	int xh=1;
	while(cases--)
	{
		ans=0;
		scanf("%d",&n);
		for(int i=0;i<n;i++)
		{
			scanf("%d",&s[i]);
		}
		mergeSort(s,temp,0,n-1);
		printf("Scenario #%d:\n",xh++);
		printf("%d\n\n",ans);
	}
	
	return 0;
 } 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值