题意:有n个新人,每个人的分数为a[i]。然后有n场比赛,每个比赛都有个最低标准b[i]。比如说b[i]=0,那么就是找到a[i]分数中最小的,不要被题目中说的b[j]+1迷惑,文字游戏。
一般思路:a[0]到a[n-1]储存a的分数,然后sort a数组。然后再扫一遍b数组。cout<<a[ b[i] ],依次输出a数组中第b[i]小的。但是会超时TLE
不难发现,我们的sort做了无用功,我们只需要找到第k大的,不一定要把a数组排好。
STL::nth_element(array,array+k,array+n);可以对数组进行部分快排,让array[k]为中心,中心左面的都比中心小中心右面的都比中心大,不难发现
STL::nth_element(array,array+n-1,array+n) == STL::sort(array,array+n)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int maxv = 1e7 + 5;
unsigned a[maxv], x, y, z, A, B, C;
struct Node {
int id, key;
unsigned value;
} node[105];
bool cmp(Node a, Node b) {
return a.key > b.key;
}
bool cmp2(Node a, Node b) {
return a.id < b.id;
}
unsigned rng61() {
unsigned t;
x ^= x << 16;
x ^= x >> 5;
x ^= x << 1;
t = x;
x = y;
y = z;
z = t ^ x ^ y;
return z;
}
int main(void) {
int n, m, kase = 1;
while (cin >> n >> m >> A >> B >> C) {
cout << "Case #" << kase++ << ":";
x = A, y = B, z = C;
for (int i = 0; i < n; i++)
a[i] = rng61();
for (int i = 1; i <= m; i++) {
cin >> node[i].key;
node[i].id = i;
}
sort(node + 1, node + 1 + m, cmp);
int nn = n;
for (int i = 1; i <= m; i++) {
int key = node[i].key;
nth_element(a, a + key, a + nn);
nn = key;
node[i].value = a[key];
}
sort(node + 1, node + 1 + m, cmp2);
for (int i = 1; i <= m; i++)
cout << " " << node[i].value;
cout << endl;
}
return 0;
}