Cod sursa(job #952629)

Utilizator primulDarie Sergiu primul Data 23 mai 2013 19:06:34
Problema Statistici de ordine Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.2 kb
#include <fstream>
#include <ctime>
#include <cstdlib>
using namespace std;
 
#define QUICK 0
 
inline bool maiMic(int a, int b) {
    return a < b;
}
 
inline bool maiMare(int a, int b) {
    return a > b;
}
 
void cleanup(int v[], int& n, int p, bool(*op)(int, int)) {
    v[0] = 0;
    for (int i = 1 ; i <= n ; i++)
        if (op(v[i], p))
            v[++v[0]] = v[i];
    n = v[0];
}
 
int rang(int v[], int n, int p) {
    int nr = 0;
 
    for (int i = 1 ; i <= n ; i++)
        if (v[i] <= p)
            ++nr;
 
    return nr;
}
 
int best(int v[], int n, bool(*op)(int, int)) {
    int rez = v[1];
 
    for (int i = 2 ; i <= n ; i++)
        if (op(v[i], rez))
            rez = v[i];
 
    return rez;
}
 
int sdoQuick(int v[], int n, int k) {
    srand(time(NULL));
 
    while (k != 1 && k != n) {
        int p = v[1 + rand() % n], nr;
        nr = rang(v, n, p);
 
        if (nr == k)
            return p;
 
        if (nr < k) {
            k -= nr;
            cleanup(v, n, p, maiMare);
        } else
            cleanup(v, n, p, maiMic);
    }
 
    if (k == 1)
        return best(v, n, maiMic);
    return best(v, n, maiMare);
}
 
int sdoBS(int v[], int n, int k){
    int rez, step, Q;
 
    rez = best(v, n, maiMic);
    Q = best(v, n, maiMare) - rez;
 
    for (step = 1 ; step <= Q ; step <<= 1);
    step >>= 1;
 
    for ( ; step && k != 1 && k != n ; step >>= 1){
        Q = rang(v, n, rez + step);
 
        if (k == Q){
            cleanup(v, n, rez + step + 1, maiMic);
            return best(v, n, maiMare);
        }
 
        if (Q < k){
            k -= Q;
            rez += step;
            cleanup(v, n, rez, maiMare);
        } else
            cleanup(v, n, rez + step, maiMic);
    }
 
    if (k == 1)
        return best(v, n, maiMic);
    return best(v, n, maiMare);
}
 
const int N = 1 + 3e6;
 
int v[N], n;
 
ifstream in("sdo.in");
ofstream out("sdo.out");
 
int main(){
    int k;
 
    in >> n >> k;
 
    for (int i = 1 ; i <= n ; i++)
        in >> v[i];
 
    if (QUICK)
        out << sdoQuick(v, n, k) << "\n";
    else
        out << sdoBS(v, n, k) << "\n";
 
    return 0;
}