【基础】1019 逆序数

版权声明:本人菜鸟一只,如文章有错误或您有高见,请不吝赐教 https://blog.csdn.net/qq_41138935/article/details/83831182

一个一个比,数据太大就会超时。代码如下:

#include<iostream>
using namespace std;
int a[50005];
int main(){
	int n;
	long long ans=0;
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>a[i];
	for(int i=0;i<n-1;i++)
		for(int j=i+1;j<n;j++)
			if(a[i]>a[j])
				ans++;

	cout<<ans<<endl;
	return 0;
} 

利用归并排序,代码如下:

#include<iostream>
#include<algorithm>
using namespace std;
const int n=50005;
int arr[n],brr[n];// arr为原数组,brr为临时数组,n为个人定义的长度
long merge(int low,int mid,int high)
{
	int i=low,j=mid+1,k=low;
	long count=0;
	while(i<=mid&&j<=high)
		if(arr[i]<=arr[j])// 此处为稳定排序的关键,不能用小于
			brr[k++]=arr[i++];
		else
		{
			brr[k++]=arr[j++];
			count+=j-k;// 每当后段的数组元素提前时,记录提前的距离 
		}
	while(i<=mid)
		brr[k++]=arr[i++];
	while(j<=high)
		brr[k++]=arr[j++];
	for(i=low;i<=high;i++)// 写回原数组
		arr[i]=brr[i];
	
	return count;
}
long mergeSort(int a,int b)// 下标,例如数组int arr[5],全部排序的调用为mergeSort(0,4)
{
	if(a<b)
	{
		int mid=(a+b)/2;
		long count=0;
		count+=mergeSort(a,mid);
		count+=mergeSort(mid+1,b);
		count+=merge(a,mid,b);	
		return count;
	}
	return 0;
}
int main(){ 
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>arr[i];
	cout<<mergeSort(0,n-1)<<endl;
	return 0;
}

最难理解的是: count+=j-k;// 每当后段的数组元素提前时,记录提前的距离

拿数组 数组 2 4 3 1 递归【分】

注意:每层递归arr的值会变,左右两边按照从小到大排序。

  2   4   |   1   3

2       4 | 3       1

可以这样理解:

数组:2431

第一次1前移1位,2413

第二次1前移2位,1243

第三次3前移1位,1234

把提前的距离相加,得到逆序数。

猜你喜欢

转载自blog.csdn.net/qq_41138935/article/details/83831182