Cod sursa(job #457672)

Utilizator tomescu_alinTomescu Alin tomescu_alin Data 20 mai 2010 21:08:47
Problema Statistici de ordine Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.52 kb
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <fstream>

using namespace std;

typedef unsigned long ulong;

ulong partition(ulong a[], ulong low, ulong high, ulong pivot)
{
	/**
	 *	All the elements before the leftbound index (exclusive) are less than the pivot.
	 *	We will increase this leftbound index as we find elements that are less than the
	 *	pivot.
	 *
	 *	The trick is we go past elements that are greater than the pivot leaving them where
	 *	they are. These bigger elements will get swapped with smaller elements whenever the 
	 *	leftwall is advanced.
	 */
	ulong leftbound = low;
	
	/**
	 *	We will move the pivot onto the first position.
	 */
	swap(a[low], a[pivot]);
	ulong& pivotValue = a[low];
	
	/**
	 *	For the remaining elements, advance the leftwall as you find elements
	 *	smaller than the pivot. When you find bigger elements than the pivot 
	 *	leave them into place. They will later get swapped with smaller elements
	 *	as the leftwall advances.
	 */
	for(ulong i = low + 1; i < high; i++)
	{
		if(a[i] < pivotValue)
		{
			leftbound++;
			swap(a[i], a[leftbound]);
		}
	}
	
	/**
	 *	Finally put the pivot where it belongs.
	 */
	swap(a[leftbound], a[low]);
	
	return leftbound;
}

ulong kth_smallest_helper(ulong a[], ulong k, ulong low, ulong high)
{
	/**
	 *	Get a random pivot in [low, high) range.
	 */
	ulong pivot = (rand() % (high - low)) + low;
	
	/**
	 *	Partition the array around the pivot, left <= pivot <= right.
	 */
	pivot = partition(a, low, high, pivot);
	
	/**
	 *	If we got lucky and the pivot turned up on the kth position then
	 *	we found the kth smallest element.
	 */
	if(pivot == k-1)
	{
		return a[pivot];
	}
	/**
	 *	If we didn't get lucky, we can either way just look on one side of
	 *	the pivot for the kth element, depending on where the pivot ended up
	 *	relative to k.
	 */
	else if(k - 1 < pivot)
	{
		return kth_smallest_helper(a, k, low, pivot);
	}
	else
	{
		return kth_smallest_helper(a, k, pivot + 1, high);
	}
}

ulong kth_smallest(ulong a[], ulong k, ulong length)
{
	return kth_smallest_helper(a, k, 0, length);
}

int main()
{	
	const char * inFile = "sdo.in";
	const char * outFile = "sdo.out";
	
	ifstream fin(inFile);
	ofstream fout(outFile);
	
	/**
	 *	Read the data in.
	 */
	ulong n, k;
	fin >> n >> k;
	
	ulong a[n];
	for(ulong i = 0; i < n; i++)
		fin >> a[i];
	
	fout << kth_smallest(a, k, n);
	
	fin.close();
	fout.close();
	return 0;
}