diff --git a/additional_tasks/heap_exe/CMakeLists.txt b/additional_tasks/heap_exe/CMakeLists.txt new file mode 100644 index 00000000..0e239848 --- /dev/null +++ b/additional_tasks/heap_exe/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.10) + +get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) +string(REPLACE " " "_" PROJECT_NAME ${PROJECT_NAME}) +project(${PROJECT_NAME} C CXX) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +file(GLOB_RECURSE source_list "src/*.cpp" "src/*.hpp") +file(GLOB_RECURSE lib_source_list "../lib/src/*.cpp" "../lib/src/*.hpp") +file(GLOB_RECURSE main_source_list "src/main.cpp") +file(GLOB_RECURSE test_source_list "src/*.cpp") +file(GLOB_RECURSE test_list "src/*test.cpp") + +list(REMOVE_ITEM test_source_list ${main_source_list}) +list(REMOVE_ITEM source_list ${test_list}) + +include_directories(${PROJECT_NAME} PUBLIC src) +include_directories(${PROJECT_NAME} PUBLIC ../lib/src) + +add_executable(${PROJECT_NAME} ${source_list}) +target_link_libraries(${PROJECT_NAME} PUBLIC Utils) + +# Locate GTest +enable_testing() +find_package(GTest REQUIRED) +include_directories(${GTEST_INCLUDE_DIRS}) + +# Link runTests with what we want to test and the GTest and pthread library +add_executable(${PROJECT_NAME}_tests ${test_source_list}) +target_link_libraries( + ${PROJECT_NAME}_tests + GTest::gtest_main + Utils +) + +include(GoogleTest) +gtest_discover_tests(${PROJECT_NAME}_tests) diff --git a/additional_tasks/heap_exe/README.md b/additional_tasks/heap_exe/README.md new file mode 100644 index 00000000..25477815 --- /dev/null +++ b/additional_tasks/heap_exe/README.md @@ -0,0 +1,12 @@ +# Покупатель рыбы +Вася решил питаться рыбой. Он решил, что в течение N дней он должен съедать по одной рыбе каждый день. К сожалению, рыба — товар скоропортящийся и может храниться не более K дней, включая день покупки. С помощью методов машинного обучения Вася предсказал цены на рыбу на N дней вперёд. +Помогите Васе определить, в какие дни и сколько рыбы нужно покупать, чтобы потратить как можно меньше денег. + +# Формат ввода +Сначала вводится два целых числа N и K (1 ≤ N, K ≤ 100 000) — количество дней, в течение которых нужно питаться рыбой, и срок хранения рыбы соответственно. +Потом вводится N чисел: стоимость рыбы в этот день Ci (1 ≤ Ci ≤ 106). + +# Формат вывода +Выведите минимальную сумму, потраченную на рыбу. +Затем выведите N чисел — количество купленных рыб в каждый из дней. +Если правильных ответов несколько — выведите любой из них. \ No newline at end of file diff --git a/additional_tasks/heap_exe/src/heap.cpp b/additional_tasks/heap_exe/src/heap.cpp new file mode 100644 index 00000000..07634633 --- /dev/null +++ b/additional_tasks/heap_exe/src/heap.cpp @@ -0,0 +1,83 @@ +#include "heap.hpp" + +void Heap::SiftUp(int i) { + while (a[i] < a[i / 2]) { + std::swap(a[i], a[i / 2]); + i /= 2; + } +} + +void Heap::SiftDown(int i) { + while (2 * i < n) { + int j = -1; + if (a[2 * i] < a[i]) { + j = 2 * i; + } + if (2 * i + 1 < n && a[2 * i + 1] < a[i] && + (j == -1 || a[2 * i] > a[2 * i + 1])) { + j = 2 * i + 1; + } + if (j == -1) + break; + else { + std::swap(a[i], a[j]); + i = j; + } + } +} + +int Heap::size() { return a.size(); } + +int Heap::GetMin() { return a[0]; } + +void Heap::Insert(int x) { + a.push_back(x); + n++; + SiftUp(n - 1); +} + +void Heap::extractMin() { + a[0] = a[n]; + a.erase(a.begin() + n - 1); + n--; + SiftDown(0); +} + +std::pair> Heap_exe(int n, int k, std::vector a) { + Heap useful_elements; + std::map indx; + + std::vector ans(n, 0); + + long long i = 0; + long long ans0 = 0; + long long j = 0; + + while (j < n) { + while (j - i < k && j < n) { + if (a[j] < a[i]) { + indx[a[j]] = j; + useful_elements.Insert(a[j]); + break; + } + + if (i != j) { + indx[a[j]] = j; + useful_elements.Insert(a[j]); + } + + ans0 += a[i]; + ans[i]++; + + j++; + } + + if (useful_elements.size() != 0) { + i = indx[useful_elements.GetMin()]; + useful_elements.extractMin(); + } else { + i = j; + } + } + return {ans0, ans}; +} \ No newline at end of file diff --git a/additional_tasks/heap_exe/src/heap.hpp b/additional_tasks/heap_exe/src/heap.hpp new file mode 100644 index 00000000..bd967517 --- /dev/null +++ b/additional_tasks/heap_exe/src/heap.hpp @@ -0,0 +1,18 @@ +#include +#include + +class Heap { + public: + void SiftUp(int i); + void SiftDown(int i); + void Insert(int x); + int GetMin(); + void extractMin(); + int size(); + + private: + std::vector a; + int n = 0; +}; + +std::pair> Heap_exe(int n, int k, std::vector a); \ No newline at end of file diff --git a/additional_tasks/heap_exe/src/main.cpp b/additional_tasks/heap_exe/src/main.cpp new file mode 100644 index 00000000..c3aeba4b --- /dev/null +++ b/additional_tasks/heap_exe/src/main.cpp @@ -0,0 +1 @@ +int main() { return 0; } \ No newline at end of file diff --git a/additional_tasks/heap_exe/src/test.cpp b/additional_tasks/heap_exe/src/test.cpp new file mode 100644 index 00000000..0ac5ce13 --- /dev/null +++ b/additional_tasks/heap_exe/src/test.cpp @@ -0,0 +1,21 @@ + +#include + +#include + +#include "heap.hpp" + +TEST(heap, Simple1) { + ASSERT_EQ(Heap_exe(2, 1, {1, 2}), + (std::pair>{3, {1, 1}})); +} + +TEST(heap, Simple2) { + ASSERT_EQ(Heap_exe(2, 1, {1, 2}), + (std::pair>{3, {1, 1}})); +} + +TEST(heap, Simple3) { + ASSERT_EQ(Heap_exe(6, 3, {3, 8, 9, 1, 4, 1}), + (std::pair>{12, {3, 0, 0, 3, 0, 0}})); +}