Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- using namespace std;
- #include <fstream>
- enum sort_type
- {
- heap_max = 0,
- heap_min = 1
- };
- struct heap_elements
- {
- int value;
- int own_ID;
- };
- bool operator<(const heap_elements& a, const heap_elements& b)
- {
- return (a.value < b.value);
- }
- class Heap
- {
- std::vector<struct heap_elements> h;
- int heap_size;
- public:
- Heap();
- bool isempty();
- heap_elements get_top();
- void siftup(int sort_type, std::vector<int>& ID_to_Index);
- void siftdown(int sort_type, int pos, std::vector<int>& ID_to_Index);
- void swap(int i, int j, std::vector<int>& ID_to_Index);
- void add(int sort_type, int ID, int value, std::vector<int>& ID_to_Index);
- void delete_vertex(int sort_type, int ID, std::vector<int>& ID_to_Index);
- };
- Heap::Heap()
- {
- std::vector<struct heap_elements> h;
- heap_size = 0;
- }
- heap_elements Heap::get_top()
- {
- return h[0];
- }
- bool Heap::isempty()
- {
- if (heap_size == 0)
- return true;
- return false;
- }
- void Heap::swap(int i, int j, std::vector<int>& ID_to_Index)
- {
- heap_elements buff;
- buff = h[i];
- h[i] = h[j];
- h[j] = buff;
- ID_to_Index[h[i].own_ID] = i; //На местах в этом массиве лежат айди этой кучи все ок
- ID_to_Index[h[j].own_ID] = j;
- }
- void Heap::siftup(int sort_type, std::vector<int>& ID_to_Index)
- {
- int curr = heap_size - 1;
- int parent = (curr - 1) / 2;
- while (curr > 0 & parent >= 0)
- {
- if (sort_type == heap_max & h[parent] < h[curr])
- swap(parent, curr, ID_to_Index);
- if (sort_type == heap_min & h[curr] < h[parent])
- swap(parent, curr, ID_to_Index);
- curr = parent;
- parent = (curr - 1) / 2;
- }
- }
- void Heap::siftdown(int sort_type, int pos, std::vector<int>& ID_to_Index)
- {
- int parent, max_child;
- int curr = pos;
- int child_l = 2 * curr + 1;
- int child_r = 2 * curr + 2;
- //max_child = (h[child_r] < h[child_l]) ? child_l : child_r;
- if (h[child_r] < h[child_l])
- max_child = child_l;
- else
- max_child = child_r;
- while (child_l < heap_size)
- {
- if (child_l == heap_size - 1)
- max_child = child_l;
- else if (h[child_r] < h[child_l])
- max_child = child_l;
- else
- max_child = child_r;
- if (sort_type == heap_max & h[curr] < h[max_child])
- swap(curr, max_child, ID_to_Index);
- if (sort_type == heap_min & h[max_child] < h[curr])
- swap(curr, max_child, ID_to_Index);
- curr = max_child;
- child_l = 2 * curr + 1;
- child_r = 2 * curr + 2;
- }
- }
- void Heap::add(int sort_type, int ID, int value, std::vector<int>& ID_to_Index)
- {
- heap_elements vertex;
- vertex.value = value;
- vertex.own_ID = ID;
- h.push_back(vertex);
- //Если это новое добавление, то надо делать пушбек,
- //а если старое, то надо просто на место ID написать heap_size
- if (ID < ID_to_Index.size()) {
- ID_to_Index[ID] = heap_size;
- }
- else {
- ID_to_Index.push_back(heap_size); //должно быть общее у двух куч
- }
- heap_size++;
- siftup(sort_type, ID_to_Index);
- }
- void Heap::delete_vertex(int sort_type, int ID, std::vector<int>& ID_to_Index)
- {
- int pos = ID_to_Index[ID];
- swap(pos, heap_size - 1, ID_to_Index); //Можно не делать свап
- h.pop_back();
- heap_size--;
- ID_to_Index[ID] = -1; //мб убрать
- siftdown(sort_type, pos, ID_to_Index);
- }
- int main()
- {
- ifstream ifs("com.txt");
- ofstream out("results.txt");
- Heap heap1;
- Heap heap2;
- std::vector<int> ID_to_Index;
- int NumberHeap;
- int curr_ID = 0;
- char c;
- int N, M, K, ID, ID_root1, root2_ID, ID_root2, count = 1;
- N = 49;
- M = 97;
- K = 3;
- int R = 0, L = 0;
- //int a[N] = { 4, 2, 1, 3, 6, 5, 7 };
- int a[N] = {9, 48, 20, 13, 40, 47, 19, 30, 3, 10, 18, 1, 36, 8, 44, 29, 12, 22, 49, 6, 37, 24, 46, 35, 38, 7, 17, 23, 45, 11, 33, 4, 14, 31, 25, 27, 28, 26, 5, 39, 34, 2, 42, 43, 15, 32, 21, 41, 16};
- int ID_to_HeapNumber[N]; //При перебрасывании в другую кучу
- heap1.add(heap_max, curr_ID, a[0], ID_to_Index);
- ID_to_HeapNumber[curr_ID] = 1; //Обновляю ID_to_HeapNumber
- curr_ID++;
- //char commands[M] = {"R","R","R","L","R","R","L","L","R","R","L","L","L","R","R","R","L","R","R","L","L","R","R","L","L","L","R","R","R","L","R","R","L","L","R","R","L","L","L","R","R","R","L","R","R","L","L","R","R","L","L","L","R","R","R","L","R","R","L","L","R","R","L","L","L","R","R","R","L","R","R","L","L","R","R","L","L","L"};
- for (int i = 0; i < M; ++i)
- {
- ifs >> c;
- //cout << "c=" << c << endl;
- //c = commands[i];
- if (c == 'R')
- {
- count++;
- R++;
- if (count < K)
- {
- heap1.add(heap_max, curr_ID, a[R], ID_to_Index);
- ID_to_HeapNumber[curr_ID] = 1; //Обновляю ID_to_HeapNumber
- curr_ID++;
- cout << "-1 ";
- }
- if (count == K)
- {
- heap1.add(heap_max, curr_ID, a[R], ID_to_Index);
- ID_to_HeapNumber[curr_ID] = 1; //Обновляю ID_to_HeapNumber
- curr_ID++;
- int l = heap1.get_top().value;
- //char ch = l + '0';
- //out << ch << " ";
- cout << heap1.get_top().value << " ";
- }
- if (count > K)
- {
- if (a[R] > heap1.get_top().value)
- {
- heap2.add(heap_min, curr_ID, a[R], ID_to_Index);
- ID_to_HeapNumber[curr_ID] = 2; //Обновляю ID_to_HeapNumber
- curr_ID++;
- cout << heap1.get_top().value << " ";
- }
- if (a[R] <= heap1.get_top().value)
- {
- heap_elements root1, root2;
- //Запоминаю корень 1 кучи
- root1 = heap1.get_top();
- ID_root1 = root1.own_ID;
- // удаляю корень 1 кучи из 1 кучи
- heap1.delete_vertex(heap_max, ID_root1, ID_to_Index);
- // Добавляю корень 1 кучи во 2 кучу не меняя ID
- heap2.add(heap_min, ID_root1, root1.value, ID_to_Index);
- ID_to_HeapNumber[ID_root1] = 2; //Обновляю ID_to_HeapNumber
- //Добавляю в 1 кучу a[R] меняя айди
- heap1.add(heap_max, curr_ID, a[R], ID_to_Index);
- ID_to_HeapNumber[curr_ID] = 1; //Обновляю ID_to_HeapNumber
- curr_ID++;
- cout << heap1.get_top().value << " ";
- }
- }
- }
- else
- {
- L++;
- count--;
- ID = L - 1;
- NumberHeap = ID_to_HeapNumber[ID];
- //Если лежит в куче1 то удаляем там, иначе во 2
- if (NumberHeap == 1)
- heap1.delete_vertex(heap_max, ID, ID_to_Index);
- else
- heap2.delete_vertex(heap_min, ID, ID_to_Index);
- if (count >= K)
- {
- //Если удалили из 2 кучи, то первая не пострадала и просто принтим
- if (NumberHeap == 2)
- {
- cout << heap1.get_top().value << " ";
- }
- else
- {
- //Запоминаю вершину кучи2
- heap_elements root2 = heap2.get_top();
- root2_ID = root2.own_ID;
- //Удаляем вершину кучи2, т.к. теперь она в куче1
- heap2.delete_vertex(heap_min, root2_ID, ID_to_Index);
- //Добавляем вершину кучи2 в кучу1 не меняя индекс чтобы стало K штук
- heap1.add(heap_max, root2_ID, root2.value, ID_to_Index);
- ID_to_HeapNumber[root2_ID] = 1; //Обновляю ID_to_HeapNumber
- cout << heap1.get_top().value << " ";
- }
- }
- else
- {
- cout << "-1 ";
- }
- }
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment