先贴一个普通的利用快拍的topk算法,后面再详细分析这个问题以及各种情况下的应用
#include<cstdio>
#include<algorithm>
#include<cassert>
#include<map>
#include<iostream>
#include<cstring>
#include<string>
#include<set>
#include<vector>
#include<cmath>
#include<iostream>
#include<fstream>
#include<sstream>
#include<queue>
using namespace std;
#define DBG false
#define out(x) cout << #x << ": " << x << " in line : " << __LINE__ << endl;
typedef long long int64;
inline int Rint(){int x; scanf("%d", &x); return x;}
// n >= 1
// a[0, p-1] >= a[p] > a[p + 1, n - 1]
int partition(int *a, int n){
if(n <= 0)
return -1;
swap(a[n - 1], a[rand() % n]);
int target = a[n - 1];
int p = -1;
for(int i = 0; i < n; ++ i)
if(a[i] >= target){
++p;
swap(a[p], a[i]);
}
return p;
}
void top_k_sort(int *a, int n, int k){
if(k <= 0 || k == n)
return ;
int p = partition(a, n);
if(p + 1 == k)
return;
if(p + 1 > k)
top_k_sort(a, p, k);
else
top_k_sort(a + p + 1, n - (p + 1), k - (p + 1));
}
int a[] = {1, 3, 2, 1, 2, 6};
int main(){
top_k_sort(a, 6, 3);
for(int i = 0; i < 3; ++ i)
printf("%d ", a[i]);
printf("\n");
return 0;
}