目录
题目
算法标签: 分治, 快速选择算法, P a r t i t i o n Partition Partition算法
思路
每次选择一个基准元素, 进行考虑
H o a r e Hoare Hoare划分方法
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 10010, M = 30010;
int n, k, w[N];
int cnt;
bool vis[M];
int find(int l, int r) {
if (l == r) return w[l];
int mid = w[l + r >> 1];
int i = l - 1, j = r + 1;
while (i < j) {
while (w[++i] < mid);
while (w[--j] > mid);
if (i < j) swap(w[i], w[j]);
}
if (k <= j) return find(l, j);
return find(j + 1, r);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> k;
for (int i = 1; i <= n; ++i) {
int val;
cin >> val;
if (!vis[val]) {
w[++cnt] = val;
vis[val] = true;
}
}
if (cnt < k) {
cout << "NO RESULT" << "\n";
return 0;
}
int ans = find(1, cnt);
cout << ans << "\n";
return 0;
}
* L o m u t o Lomuto Lomuto划分方法
这个逻辑的边界问题处理非常麻烦
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 10010, M = 30010;
int n, k, cnt;
int w[N];
bool vis[M];
int find(int l, int r) {
if (l == r && l == k) return w[l];
if (l < k) {
int val = w[l];
int i = l, j = r;
while (i < j) {
while (i < j && w[j] > val) j--;
if (i < j) swap(w[i], w[j]);
while (i < j && w[i] <= val) i++;
if (i < j) swap(w[i], w[j]);
}
w[i] = val;
if (i == k) return w[k];
else if (k < i) return find(l, i - 1);
return find(i + 1, r);
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> k;
for (int i = 0; i < n; ++i) {
int val;
cin >> val;
if (!vis[val]) {
w[++cnt] = val;
vis[val] = true;
}
}
if (cnt < k) {
cout << "NO RESULT" << "\n";
return 0;
}
int ans = find(1, cnt);
cout << ans << "\n";
return 0;
}

京公网安备 11010502036488号