HDU 6040 nth_element快排

 题意:有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;
}

猜你喜欢

转载自blog.csdn.net/shadandeajian/article/details/81459691
今日推荐