poj - 1804归并求逆序对

本文介绍了一种使用归并排序算法计算数组中逆序对数量的方法,并提供了详细的C++实现代码。通过将数组分为两部分分别排序,再合并过程中统计逆序对的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


https://vjudge.net/problem/poj-1804


这题也可以用树状数组来做的;想到归并排序求逆序对,也是一种方法,随便说说归并排序:


归并排序是把要排序的数组分成两个部分进行排序,然后将两个部分进行归并,然后在合并的时候因为两个部分都是有序的,所以当a[i] > a[j]的时候,因为i后面的数都不小于a[i],所以后面的数自然也大于a[j],所以加上的是mid - i + 1的逆序对;


#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 1000 + 10;
int a[maxn];
int ans;
void merge(int l,int r)
{
	int mid = (l + r) >> 1;
	int i = l;
	int j = mid + 1;
	int temp[maxn];
	int k = l;
	while(i <= mid && j <= r)
	{
		if(a[i] > a[j])
		{
			temp[k ++] = a[j ++];
			ans += mid - i + 1;//因为前半部分已经排好序了,后面的数都比这个数大 
		}
		else 
		{
			temp[k ++] = a[i ++];
		}
	}
	while(i <= mid)
	{
		temp[k ++] = a[i ++];
	}
	while(j <= r)
	{
		temp[k ++] = a[j ++];
	}
	for(i = l; i <= r; i ++)
	{
		a[i] = temp[i];
	}
	
}
void merge_sort(int l,int r)
{
	if(l == r)
	return ;
	int mid = (l + r) >> 1;
	merge_sort(l ,mid);
	merge_sort(mid + 1,r);
	merge(l,r);
}
int main()
{
	int Tcase;
	scanf("%d",&Tcase);
	for(int ii = 1; ii <= Tcase; ii ++)
	{
		ans = 0;
		int n;
		scanf("%d",&n);
		for(int i = 1; i <= n; i ++)
		scanf("%d",&a[i]);
		merge_sort(1,n);
//		for(int i = 1; i <= n; i ++)
//		cout << a[i] << " ";
//		cout << endl; 
		cout << "Scenario #"<<ii << ":" << endl;
		cout << ans << endl << endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值