基本算法--分治法(快排,归并)习题

参考基本算法-分治法(快排,归并)-CSDN博客​​​​​​ 模板进行练习,旨在加强两个模板运用。

1.求逆序对(归并排序)

题目来源:P1908 逆序对 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题目描述

猫猫 TOM 和小老鼠 JERRY 最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。

最近,TOM 老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中 ai​>aj​ 且 i<j 的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。注意序列中可能有重复数字。

输入格式:

第一行,一个数 n,表示序列中有 n个数。

第二行 n 个数,表示给定的序列。序列中每个数字不超过 1e9。

输出格式

输出序列中逆序对的数目。

思路

板子题,参考基本算法-分治法(快排,归并)-CSDN博客 归并排序模板加以修改,以cnt作为逆序对的个数。

当q[i]>q[j]时,cnt+=mid-i+1;即可求出逆序对的个数。

注意:此题数据量比较大,要开long long ,用int 过不去。

完整代码

#include<bits/stdc++.h>
using namespace std;

const int N=5e5+10;
long long q[N],tmp[N],cnt=0;

void merge_sort(long long q[],long long l ,long long r){
	if(l>=r) return;
	long long mid=l+r>>1;
	merge_sort(q,l,mid);
	merge_sort(q,mid+1,r);
	
	long long k=0,i=l,j=mid+1;
	while(i<=mid&&j<=r){
		if(q[i]<=q[j]) tmp[k++]=q[i++];

		else {
			tmp[k++]=q[j++];
			cnt+=mid-i+1;			
		}
	}
	while(i<=mid) tmp[k++]=q[i++];
	while(j<=r) tmp[k++]=q[j++];
	
	for(long long i=l,j=0;i<=r;i++,j++) q[i]=tmp[j];
}

int main(){
	long long n;
	cin>>n;
	for(long long i=0;i<n;i++) scanf("%lld",&q[i]);
	merge_sort(q,0,n-1);
	cout<<cnt<<endl;
	return 0;
}

2.求第 k 小的数(快速排序)

题目来源:P1923 【深基9.例4】求第 k 小的数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题目描述

输入 n(1≤n<50000001≤n<5000000 且 n 为奇数)个数字 ai​(1≤ai​<1e9),输出这些数字的第 k 小的数。最小的数是第 0 小。

请尽量不要使用 nth_element 来写本题,因为本题的重点在于练习分治算法。

思路

方法一:

用快速排序直接排出q[]的大小,输出即可。

完整代码
#include<bits/stdc++.h>
using namespace std;

const int N=5e6+10;
typedef long long ll;
ll q[N];

void quick_sort(ll q[],ll l,ll r){
	if(l>=r) return;
	
	ll i=l-1,j=r+1,x=q[l+r>>1];
	while(i<j){
		do i++;while(q[i]<x);
		do j--;while(q[j]>x);
		if(i<j) swap(q[i],q[j]);
	}
	quick_sort(q,l,j);
	quick_sort(q,j+1,r);
}

int main(){
	ll n,m;
	cin>>n>>m;
	for(int i=0;i<n;i++) scanf("%lld",&q[i]);
	quick_sort(q,0,n-1);
	cout<<q[m]<<endl;
	return 0;
}

方法二:

用c++自带STL库函数sort()排除大小,输出即可。

完整代码
#include<bits/stdc++.h>
using namespace std;

const int N=5e6+10;
typedef long long ll;
ll q[N];


int main(){
	ll n,m;
	cin>>n>>m;
	for(int i=0;i<n;i++) scanf("%lld",&q[i]);
	sort(q,q+n);
	cout<<q[m]<<endl;
	return 0;
}

感谢大家的观看!

相关推荐

  1. 基本算法--分治归并习题

    2024-01-20 21:34:02       62 阅读
  2. 常见排序算法,希尔,归并,堆

    2024-01-20 21:34:02       23 阅读
  3. 【排序算法】之

    2024-01-20 21:34:02       61 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-20 21:34:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-20 21:34:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-20 21:34:02       82 阅读
  4. Python语言-面向对象

    2024-01-20 21:34:02       91 阅读

热门阅读

  1. 鸿蒙harmony--HTTP数据请求的简单使用

    2024-01-20 21:34:02       56 阅读
  2. 微信小程序实现下拉简单展示接口数据

    2024-01-20 21:34:02       57 阅读
  3. 嵌入式C语言--LD文件的概念

    2024-01-20 21:34:02       60 阅读
  4. Jtti:Ubuntu中如何搭建LAMP开发环境

    2024-01-20 21:34:02       53 阅读
  5. 《python算法与数据结构2000讲》0217. 存在重复元素

    2024-01-20 21:34:02       60 阅读
  6. 计算机网络(第六版)复习提纲5

    2024-01-20 21:34:02       56 阅读
  7. 头歌C++基础语法进阶练习题

    2024-01-20 21:34:02       61 阅读