Pagini recente » Cod sursa (job #2453577) | Cod sursa (job #1447734) | Cod sursa (job #1021247) | Cod sursa (job #283215) | Cod sursa (job #1077624)
#include <fstream>
using namespace std;
namespace e_041_sdo_heap
{
template <typename T, int MAX_N>
class heap
{
private:
T a[MAX_N];
int N;
int parent(int i) { return (i - 1) / 2; }
inline int left_child(int i) { return 2 * i + 1; }
inline int right_child(int i) { return 2 * i + 2; }
public:
heap() : N(0) {}
~heap() {}
T& operator () (int i) { return a[i]; }
int size() { return N; }
void insert(T x)
{
a[N++] = x;
update_position(N - 1);
}
void remove(int position)
{
exchange_positions(position, N - 1); //exchange with the last element
N--; //remove the last element
update_position(position); //update the heap
}
void replace(int position, int new_val)
{
a[position] = new_val;
update_position(position);
}
private:
/**
* Update the heap if the element at the given position has changed its value.
* The new value might not respect the heap structure. The other elements are in the heap format.
* Usefull after one element was inserted/deleted at the end of the vector.
*/
void update_position(int position)
{
int current_pos = position;
int parent_pos;
//upward updating
while (current_pos > 0 && a[current_pos] > a[parent_pos = parent(current_pos)]) {
//exchange the places in heap
exchange_positions(current_pos, parent_pos);
current_pos = parent_pos;
}
//downward updating
int next_pos;
//update only if upward updating wasn't performed
if (current_pos == position) {
while (current_pos >= 0)
{
next_pos = -1;
//check the children of the current node and their values
int pos_left_child = left_child(current_pos);
int pos_right_child = right_child(current_pos);
bool left_available = false, right_available = false;
if (pos_left_child < N && a[pos_left_child] > a[current_pos]) {
next_pos = pos_left_child; left_available = true;
}
if (pos_right_child < N && a[pos_right_child] > a[current_pos]) {
next_pos = pos_right_child;
right_available = true;
}
//if the node has two children choose the child with the maximum value
if (left_available && right_available) {
if (a[pos_left_child] > a[pos_right_child]) next_pos = pos_left_child;
else next_pos = pos_right_child;
}
//if necessary, exchange the places in heap
if (next_pos >= 0) exchange_positions(current_pos, next_pos);
current_pos = next_pos;
}
}
}
inline void exchange_positions(int pos_i, int pos_j)
{
//exchange the values
T aux = a[pos_i];
a[pos_i] = a[pos_j];
a[pos_j] = aux;
}
};
}
//int sdo_heap_minimal()
int main()
{
string in_file = "sdo.in";
string out_file = "sdo.out";
int N, K;
const int MAX_K = 1000000;
e_041_sdo_heap::heap<int, MAX_K> heap_;
ifstream ifs(in_file);
ifs >> N >> K;
int x;
ifs >> x;
heap_.insert(x);
for (int i = 1; i < N; i++) {
int x;
ifs >> x;
if (heap_.size() < K) heap_.insert(x);
else if (x < heap_(0)) heap_.replace(0, x);
}
ifs.close();
ofstream ofs(out_file);
ofs << heap_(0);
ofs.close();
return 0;
}