逆序对问题(c++)

概念

逆序对,是什么?

一个数组 a,如果 a i > a j 并且 i < j,那么称 a i 和 a j 是逆序对。

举个例子:

这里有一个数组:a 5 = { 1 , 3 , 4 , 2 , 5 }

那么,数组中的3和2、4和2都是逆序对

题目练习

基础逆序对计数

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int n,a[1010];


int main()
{
	
	cin>>n;
	for(int i = 1;i<=n;i++)
	{
		cin>>a[i];
	}
	
	int cnt = 0;
	for(int i = 1;i<=n-1;i++)
	{
		for(int j = 1;j<=n-i;j++)
		{
			if(a[j]>a[j+1])
			{
//				cout<<a[j]<<" "<<a[j+1]<<endl;
				swap(a[j],a[j+1]);
				cnt++;
			}
		}
	}
//	for(int i = 1;i<=n;i++)
//	{
//		cout<<a[i]<<" ";
//	}
//	cout<<endl;
	cout<<cnt;
	return 0;
}

插入排序优化

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int n,a[1010];


int main()
{
	
	cin>>n;
	for(int i = 1;i<=n;i++)
	{
		cin>>a[i];
	}
	
	int cnt = 0;
	for(int i = 2;i<=n;i++)
	{
		int t = a[i];
		int j = i-1;
		for(;j>=1;j--)
		{
			if(a[j]>t) a[j+1] = a[j],cnt++;
			else break;
		}
		a[j+1] = t;
//		cout<<i<<" "<<j<<" "<<cnt<<endl;
//		for(int i = 1;i<=n;i++)
//		{
//			cout<<a[i]<<" ";
//		}
//		cout<<endl;
	}
//	for(int i = 1;i<=n;i++)
//	{
//		cout<<a[i]<<" ";
//	}
	cout<<cnt;
	
	return 0;
}

大规模数据的逆序对计数

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int n,a[100010];
int cnt;


void guibing(int,int);
int main()
{
	
	cin>>n;
	for(int i = 1;i<=n;i++)
	{
		cin>>a[i];
	}
	
	
	guibing(1,n);
//	for(int i = 1;i<=n;i++)
//	{
//		cout<<a[i]<<" ";
//	}
//	cout<<endl;
	cout<<cnt;
	
	return 0;
}
void guibing(int l,int r)
{
	if(l==r) return;
	int mid = (l+r)/2;
	guibing(l,mid);
	guibing(mid+1,r);
	
	int i = l;
	int j = mid+1;
	int t[100010] = {0};
	int lt = l-1;
	while(i<=mid&&j<=r)
	{
		if(a[j]<a[i])
		{
			cnt += mid-i+1;
			t[++lt] = a[j];
			j++;
		}
		else
		{
			t[++lt] = a[i];
			i++;
		}
	}
	while(i<=mid)
	{
		t[++lt] = a[i];
		i++;
	}
	while(j<=r)
	{
		t[++lt] = a[j];
		j++;
	}
//	cout<<l<<" "<<mid<<" "<<r<<" "<<cnt<<endl;
	for(int ii = l;ii<=r;ii++)
	{
		a[ii] = t[ii];
	}
	return;
	
}

最小逆序对

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int n,a[100010],b[100010];
int cnt,mi;


void guibing(int,int);
int main()
{
	
	cin>>n;
	for(int i = 1;i<=n;i++)
	{
		cin>>b[i];
	}
	mi = 999999999;
	for(int i = 1;i<=n;i++)
	{
		for(int j = 1;j<=i;j++)
		{
			a[n-i+j] = b[j];
		}
		for(int j = 1;j<=n-i;j++)
		{
			a[j] = b[i+j];
		}
		guibing(1,n);
		mi = min(mi,cnt);
		cnt = 0;
	}
	
//	for(int i = 1;i<=n;i++)
//	{
//		cout<<a[i]<<" ";
//	}
//	cout<<endl;
	cout<<mi;
	
	return 0;
}
void guibing(int l,int r)
{
	if(l==r) return;
	int mid = (l+r)/2;
	guibing(l,mid);
	guibing(mid+1,r);
	
	int i = l;
	int j = mid+1;
	int t[100010] = {0};
	int lt = l-1;
	while(i<=mid&&j<=r)
	{
		if(a[j]<a[i])
		{
			cnt += mid-i+1;
			t[++lt] = a[j];
			j++;
		}
		else
		{
			t[++lt] = a[i];
			i++;
		}
	}
	while(i<=mid)
	{
		t[++lt] = a[i];
		i++;
	}
	while(j<=r)
	{
		t[++lt] = a[j];
		j++;
	}
//	cout<<l<<" "<<mid<<" "<<r<<" "<<cnt<<endl;
	for(int ii = l;ii<=r;ii++)
	{
		a[ii] = t[ii];
	}
	return;
	
}
相关推荐
Black蜡笔小新11 小时前
自动化AI算法训练服务器DLTM制造业AI质检工作站助力制造业实现AI智检
人工智能·算法·自动化
嵌入式小能手11 小时前
飞凌嵌入式ElfBoard-进程间的通信之命名管道
linux·服务器·算法
啦哈拉哈11 小时前
Leetcode题解记录-hot100(81-100)
算法·leetcode·职场和发展
csdn_aspnet12 小时前
Java 霍尔分区算法(Hoare‘s Partition Algorithm)
java·开发语言·算法
王老师青少年编程12 小时前
信奥赛C++提高组csp-s之搜索进阶(搜索剪枝核心思想 )
c++·dfs·csp·信奥赛·搜索剪枝·搜索优化
一拳一个呆瓜12 小时前
【STL】使用 C++ 标准库标头
c++·stl
诸葛务农12 小时前
道路行驶条件下电动汽车永磁电机的有效使用寿命及永磁体的失效和回收再利用(下)
java·开发语言·算法
snow@li12 小时前
AI:理解 大数据、算法、算力、电力、生成式AI、token 之间的关系
大数据·人工智能·算法
小智老师PMP12 小时前
零基础能不能考PMP?零基础专属学习路径+全套扶持体系
学习·算法·职场和发展·软件工程·求职招聘·敏捷流程
王老师青少年编程12 小时前
信奥赛C++提高组csp-s之搜索进阶(搜索剪枝案例实践2)
c++·信奥赛·csp-s·提高组·搜索剪枝·生日蛋糕·最优性剪枝