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;
}