Sort Algorithm 排序算法专练

【Sort Algorithm 排序算法专练】

【快速排序】

第k小整数

1.第 k 小整数

题目跳转

题目描述

现有 \(n\) 个正整数,要求出这 \(n\) 个正整数中的第 \(k\) 个最小整数(相同大小的整数只计算一次)。

输入格式

第一行为 \(n\)\(k\); 第二行开始为 \(n\) 个正整数的值,整数间用空格隔开。

输出格式

\(k\)个最小整数的值;若无解,则输出 NO RESULT

样例 #1

样例输入 #1

10 3
1 3 3 7 2 5 1 2 4 6

样例输出 #1

3

提示

\(n \leq 10000\)\(k \leq 1000\),正整数均小于 \(30000\)

思路:

快速排序模板+双指针去重,注重函数使用方式
function<void(int*,int ,int)>funcName=[&](int q[],int l,int r){}

题解:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],n,k;

void quick_sort(int q[],int l,int r){
	if(l>=r) return;
	int x=q[(l+r)>>1],i=l-1,j=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(){
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++) scanf("%d",&a[i]);

	quick_sort(a,0,n-1);

	int i=0;
	for(int j=0;j<n;j++){
		if(!j || a[j]!=a[j-1]) a[i++]=a[j];
	}
	if(k<=i) cout<<a[k-1]<<"\n";
	else cout<<"NO RESULT";
	return 0;

}

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],n,k;



int main(){
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	
	
	function <void (int*,int,int)> quick_sort1=[&](int q[],int l,int r){
		if(l>=r) return;
		int x=q[(l+r)>>1],i=l-1,j=r+1;
		while(i<j){
			do i++;while(q[i]<x);
			do j--;while(q[j]>x);
			if(i<j){
				int t=q[i];
				q[i]=q[j];
				q[j]=t;
			}
		}
		quick_sort1(q,l,j);
		quick_sort1(q,j+1,r);
	};


	quick_sort1(a,0,n-1);


	int i=0;
	for(int j=0;j<n;j++){
		if(!j || a[j]!=a[j-1]) a[i++]=a[j];
	}
	if(k<=i) cout<<a[k-1]<<"\n";
	else cout<<"NO RESULT";
	return 0;

}

【归并排序】

逆序对

2.逆序对

题目跳转

题目描述

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

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

Update:数据已加强。

输入格式

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

第二行 \(n\) 个数,表示给定的序列。序列中每个数字不超过 \(10^9\)

输出格式

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

样例 #1

样例输入 #1

6
5 4 2 6 3 1

样例输出 #1

11

提示

对于 \(25\%\) 的数据,\(n \leq 2500\)

对于 \(50\%\) 的数据,\(n \leq 4 \times 10^4\)

对于所有数据,\(n \leq 5 \times 10^5\)

请使用较快的输入输出

应该不会 \(O(n^2)\) 过 50 万吧 by chen_zhe

题解:

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

void merge_sort(vector<int> &a,int l,int r,long long &count){
    vector<int> t(r-l+10);
    if(l>=r) return ;
    int mid=(l+r)>>1;
    mergeSort(a,l,mid,count);
    mergeSort(a,mid+1,r,count);
    int i=l,j=mid+1,k=0;
    while(i<=mid && j<=r){
        if(a[i]>a[j]){
            count+=mid-i+1;
            t[k++]=a[j++];
        }
        else if(a[i]<a[j]) t[k++]=a[i++];
        else{
            int d=i+1;
            int c=0;
            while(a[i]==a[d++] && d<=mid) c++;
            count+=mid-i-c;
            t[k++]=a[j++];
        }
    }
    while(i<=mid) t[k++]=a[i++];
    while(j<=r) t[k++]=a[j++];
    for(int i=l,j=0;i<=r;i++,j++) a[i]=t[j];
}

int main(){
    int n;cin>>n;
    vector<int> a(n);
    for(int i=0;i<n;i++) cin>>a[i];
    long long count=0;
    mergeSort(a,0,n-1,count);
    cout<<count<<"\n";
    return 0;
}

posted @ 2023-01-24 22:47  哲远甄骏  阅读(17)  评论(0)    收藏  举报