Cod sursa(job #884332)

Utilizator BitOneSAlexandru BitOne Data 20 februarie 2013 21:06:23
Problema Statistici de ordine Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.57 kb
#include <vector>
#include <ctime>
#include <cstdlib>
#include <fstream>
#include <iterator>
#include <algorithm>


using namespace std;

const int NMAX = 3000011;

int v[NMAX];

inline int medianOfThree(int left, int middle, int right)
{
    if(v[left] < v[middle])
    {
	if(v[middle] < v[right])    return middle;
	else if(v[left] < v[right]) return right;
	else                        return left;
    }
    else {
	    if(v[middle] > v[right])    return middle;
	    else if(v[right] < v[left]) return right;
	    else                        return left;
         }
}

inline void _swap(int& x, int& y) {int aux = x; x = y; y = aux;}

int QuickSelect(int left, int right, int idx)
{
    if(left > right) exit(1);
    if(left == right) return v[left];
    
    int pValue, pIndex, i, j, k;
  
    _swap(v[left], v[rand() % (right - left + 1) + left]);
    pValue = v[pIndex = medianOfThree(left, (left + right) >> 1, right)];
    _swap(v[left], v[pIndex]);

    for(i = left, j = right + 1; true;)
    {
	while(v[--j] > pValue);
	while(i <= right && v[++i] < pValue);
	if(i >= j) break;
	_swap(v[i], v[j]);
    }
    _swap(v[left], v[j]);

    k = j - left + 1;
    if(idx == k) return pValue;
    if(k > idx)  return QuickSelect(left, j - 1, idx);
    return QuickSelect(j + 1, right, idx - k);
}

int main()
{
    int N, idx;
    ifstream in("sdo.in");
    ofstream out("sdo.out");

    //srand(time(NULL));
    in >> N >> idx;
    copy(istream_iterator<int>(in), istream_iterator<int>(), v + 1);
    
    out << QuickSelect(1, N, idx) << '\n';

    in.close();
    out.close();
    return EXIT_SUCCESS;
}