Pagini recente » Cod sursa (job #2563283) | Cod sursa (job #2390015) | Cod sursa (job #427371) | Cod sursa (job #2307721) | Cod sursa (job #457778)
Cod sursa(job #457778)
#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_recursive(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)
{
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 < pivot)
{
return kth_smallest_helper_recursive(a, k, low, pivot);
}
else
{
return kth_smallest_helper_recursive(a, k, pivot + 1, high);
}
}
ulong kth_smallest_helper(ulong a[], ulong k, ulong low, ulong high)
{
ulong pivot;
/**
* If we got lucky and the pivot turned up on the kth position then
* we found the kth smallest element.
*/
do
{
/**
* Get a random pivot in [low, high) range.
*/
pivot = (rand() % (high - low)) + low;
/**
* Partition the array around the pivot, left <= pivot <= right.
*/
pivot = partition(a, low, high, pivot);
/**
* If we didn't get lucky, we can look on one side of the pivot for
* the kth element, depending on where the pivot ended up relative to k.
*/
if(k < pivot)
{
high = pivot;
}
else
{
low = pivot + 1;
}
} while(pivot != k);
return a[pivot];
}
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 = new ulong[n];
for(ulong i = 0; i < n; i++)
fin >> a[i];
fin.close();
/**
* Write out the result.
*/
fout << kth_smallest(a, k - 1, n);
fout.close();
delete [] a;
return 0;
}