diff --git a/task_01/src/get_terms.hpp b/task_01/src/get_terms.hpp new file mode 100644 index 0000000..959bbe6 --- /dev/null +++ b/task_01/src/get_terms.hpp @@ -0,0 +1,27 @@ +#include +#include +#include +#include + +std::pair GetTerms(const std::vector& array, int sum) { + int n = array.size(); + + if (n == 0 || n == 1) return std::pair(-1, -1); + + int l{0}, r{n - 1}; + + int current_sum; + while (l != r) { + current_sum = array[l] + array[r]; + if (current_sum == sum) { + return std::pair(array[l], array[r]); + } else { + if (current_sum > sum) + --r; + else + ++l; + } + } + + return std::pair(-1, -1); +} \ No newline at end of file diff --git a/task_01/src/main.cpp b/task_01/src/main.cpp index 0e4393b..1216923 100644 --- a/task_01/src/main.cpp +++ b/task_01/src/main.cpp @@ -1,3 +1,31 @@ +#include #include +#include +#include +#include -int main() { return 0; } +// python3 ./scripts/run_cases.py --tasks task_01 + +int main() { + int S, N; + std::vector v; + std::string line3, line1, line2; + + getline(std::cin, line1); + getline(std::cin, line2); + getline(std::cin, line3); + + S = stoi(line1); + N = stoi(line2); + + std::istringstream is(line3); + + int x; + while (is >> x) v.push_back(x); + std::pair result = GetTerms(v, S); + if (result == std::pair(-1, -1)) + std::cout << -1 << std::endl; + else + std::cout << result.first << " " << result.second << std::endl; + return 0; +} diff --git a/task_01/src/test.cpp b/task_01/src/test.cpp index 87cef73..a80da52 100644 --- a/task_01/src/test.cpp +++ b/task_01/src/test.cpp @@ -1,5 +1,35 @@ #include +#include +#include +#include + TEST(Test, Simple) { - ASSERT_EQ(1, 1); // Stack [] + std::vector v = {1, 2, 4}; + std::vector v1 = {2, 7, 11, 15}; + std::vector v2 = {3, 7, 12}; + std::vector v3 = {-67, -42, 0, 52, 108, 252}; + std::vector v4 = {2, 4}; + ASSERT_EQ(GetTerms(v, 52), std::make_pair(-1, -1)); + ASSERT_EQ(GetTerms(v, -52), std::make_pair(-1, -1)); + ASSERT_EQ(GetTerms(v, 0), std::make_pair(-1, -1)); + ASSERT_EQ(GetTerms(v1, 9), std::make_pair(2, 7)); + ASSERT_EQ(GetTerms(v2, 19), std::make_pair(7, 12)); + ASSERT_EQ(GetTerms(v3, 10), std::make_pair(-42, 52)); + ASSERT_EQ(GetTerms(v3, 1), std::make_pair(-1, -1)); + ASSERT_EQ(GetTerms(v4, 6), std::make_pair(2, 4)); +} + +TEST(Test, Empty) { + std::vector v_empty = {}; + ASSERT_EQ(GetTerms(v_empty, 52), std::make_pair(-1, -1)); + ASSERT_EQ(GetTerms(v_empty, -52), std::make_pair(-1, -1)); + ASSERT_EQ(GetTerms(v_empty, 0), std::make_pair(-1, -1)); +} + +TEST(Test, Single) { + std::vector v_single = {0}; + ASSERT_EQ(GetTerms(v_single, 52), std::make_pair(-1, -1)); + ASSERT_EQ(GetTerms(v_single, -52), std::make_pair(-1, -1)); + ASSERT_EQ(GetTerms(v_single, 0), std::make_pair(-1, -1)); } \ No newline at end of file diff --git a/task_02/src/get_border_index.hpp b/task_02/src/get_border_index.hpp new file mode 100644 index 0000000..343c1d0 --- /dev/null +++ b/task_02/src/get_border_index.hpp @@ -0,0 +1,20 @@ +#include + +int GetBorderIndex(std::vector v) { + int N = v.size(); + + if (v[1] == 1) return 0; + if (v[N - 2] == 0) return N - 2; + + int left = 0, right = N - 1; + + while (left + 1 < right) { + int mid = (left + right) / 2; + + if (v[mid] == 1) + right = mid; + else + left = mid; + } + return left; +} \ No newline at end of file diff --git a/task_02/src/main.cpp b/task_02/src/main.cpp index 0e4393b..c0c3ea6 100644 --- a/task_02/src/main.cpp +++ b/task_02/src/main.cpp @@ -1,3 +1,23 @@ +#include #include +#include +#include +#include -int main() { return 0; } +int main() { + int N; + std::vector v; + std::string line1, line2; + + getline(cin, line1); + getline(cin, line2); + + N = stoi(line1); + + std::istringstream is(line2); + int x; + while (is >> x) v.push_back(x); + + std::cout << GetBorderIndex(v) << endl; + return 0; +} diff --git a/task_02/src/test.cpp b/task_02/src/test.cpp index ee23770..2cf98e3 100644 --- a/task_02/src/test.cpp +++ b/task_02/src/test.cpp @@ -1,5 +1,56 @@ #include +#include +#include + TEST(Test, Simple) { - ASSERT_EQ(1, 1); // placeholder + std::vector v1{0, 1}; + std::vector v2{0, 0, 0, 1, 1}; + std::vector v3{0, 0, 0, 0, 0, 1}; + std::vector v4{0, 1, 1, 1, 1}; + std::vector v5{0, 0, 1, 1, 1, 1}; + std::vector v6{0, 0, 0, 1}; + std::vector v7{0, 0, 1}; + std::vector v8{0, 1, 1}; + std::vector v9{0, 0, 0, 0, 1, 1, 1}; + std::vector v10{0, 0, 0, 0, 0, 0, 0, 0, 1}; + std::vector v11{0, 0, 0, 0, 1}; + std::vector v12{0, 0, 1, 1}; + std::vector v13{0, 1, 1, 1}; + std::vector v14{0, 1, 0, 1, 0, 1, 0, 1}; + + ASSERT_EQ(GetBorderIndex(v1), 0); + ASSERT_EQ(GetBorderIndex(v2), 2); + ASSERT_EQ(GetBorderIndex(v3), 4); + ASSERT_EQ(GetBorderIndex(v4), 0); + ASSERT_EQ(GetBorderIndex(v5), 1); + ASSERT_EQ(GetBorderIndex(v6), 2); + ASSERT_EQ(GetBorderIndex(v7), 1); + ASSERT_EQ(GetBorderIndex(v8), 0); + ASSERT_EQ(GetBorderIndex(v9), 3); + ASSERT_EQ(GetBorderIndex(v10), 7); + ASSERT_EQ(GetBorderIndex(v11), 3); + ASSERT_EQ(GetBorderIndex(v12), 1); + ASSERT_EQ(GetBorderIndex(v13), 0); +} + +void CheckAnswer(int i, std::vector v) { + ASSERT_EQ(v[i], 0); + ASSERT_EQ(v[i] + 1, 1); } + +TEST(Test, OutOfSync) { + std::vector v1{0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1}; + std::vector v2{0, 1, 0, 1, 0, 1, 0, 1}; + std::vector v3{0, 0, 0, 1, 0, 0, 0, 1}; + std::vector v4{0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1}; + std::vector v5{0, 1, 0, 1}; + std::vector v6{0, 1, 1, 1, 1, 0, 1}; + + CheckAnswer(GetBorderIndex(v1), v1); + CheckAnswer(GetBorderIndex(v2), v2); + CheckAnswer(GetBorderIndex(v3), v3); + CheckAnswer(GetBorderIndex(v4), v4); + CheckAnswer(GetBorderIndex(v5), v5); + CheckAnswer(GetBorderIndex(v6), v6); +} \ No newline at end of file diff --git a/task_03/src/get_combinations.hpp b/task_03/src/get_combinations.hpp new file mode 100644 index 0000000..5da8965 --- /dev/null +++ b/task_03/src/get_combinations.hpp @@ -0,0 +1,38 @@ +#include +#include + +const std::vector num_to_let{"abc", "def", "ghi", "jkl", + "mno", "pqrs", "tuv", "wxyz"}; +constexpr int shift = 2; + +void FillingArray(std::vector nums, int index, std::string combination, + std::vector &result) { + if (index == nums.size()) { + result.push_back(combination); + return; + } + + std::string new_combination; + for (char c : num_to_let[nums[index] - shift]) { + new_combination = combination + c; + FillingArray(nums, index + 1, new_combination, result); + } +} + +std::vector GetCombinations(std::string digits) { + std::vector nums; + for (char c : digits) { + if (c >= '2' && c <= '9') { + nums.push_back(c - '0'); + } + } + std::vector result; + + if (nums.empty()) return result; + + std::string combination; + int index = 0; + + FillingArray(nums, index, combination, result); + return result; +} \ No newline at end of file diff --git a/task_03/src/main.cpp b/task_03/src/main.cpp index 0e4393b..85f536c 100644 --- a/task_03/src/main.cpp +++ b/task_03/src/main.cpp @@ -1,3 +1,13 @@ +#include #include +#include +#include -int main() { return 0; } +int main() { + std::string digits; + getline(std::cin, digits); + + std::vector result = GetCombinations(digits); + + for (std::string str : result) std::cout << str << " "; +} diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp index 869094d..477635c 100644 --- a/task_03/src/test.cpp +++ b/task_03/src/test.cpp @@ -1,4 +1,54 @@ - #include -TEST(TopologySort, Simple) { ASSERT_EQ(1, 1); } +#include + +#include "get_combinations.hpp" + +TEST(Test, Single) { + // Одна цифра + std::vector empty{}; + std::vector v2{"a", "b", "c"}; + std::vector v3{"d", "e", "f"}; + std::vector v4{"g", "h", "i"}; + std::vector v5{"j", "k", "l"}; + std::vector v6{"m", "n", "o"}; + std::vector v7{"p", "q", "r", "s"}; + std::vector v8{"t", "u", "v"}; + std::vector v9{"w", "x", "y", "z"}; + + ASSERT_EQ(GetCombinations("0"), empty); + ASSERT_EQ(GetCombinations("1"), empty); + ASSERT_EQ(GetCombinations("2"), v2); + ASSERT_EQ(GetCombinations("3"), v3); + ASSERT_EQ(GetCombinations("4"), v4); + ASSERT_EQ(GetCombinations("5"), v5); + ASSERT_EQ(GetCombinations("6"), v6); + ASSERT_EQ(GetCombinations("7"), v7); + ASSERT_EQ(GetCombinations("8"), v8); + ASSERT_EQ(GetCombinations("9"), v9); +} + +TEST(Test, TwoDigits) { + // Две цифры + std::vector v1{"ad", "ae", "af", "bd", "be", + "bf", "cd", "ce", "cf"}; + std::vector v2{"pw", "px", "py", "pz", "qw", "qx", "qy", "qz", + "rw", "rx", "ry", "rz", "sw", "sx", "sy", "sz"}; + ASSERT_EQ(GetCombinations("23"), v1); + ASSERT_EQ(GetCombinations("79"), v2); +} + +TEST(Test, ThreeDigits) { + // Три цифры + std::vector v1{"adg", "adh", "adi", "aeg", "aeh", "aei", "afg", + "afh", "afi", "bdg", "bdh", "bdi", "beg", "beh", + "bei", "bfg", "bfh", "bfi", "cdg", "cdh", "cdi", + "ceg", "ceh", "cei", "cfg", "cfh", "cfi"}; + ASSERT_EQ(GetCombinations("234"), v1); +} + +TEST(Test, Empty) { + // Пустая строка + std::vector empty{}; + ASSERT_EQ(GetCombinations(""), empty); +} \ No newline at end of file diff --git a/task_04/src/stack.cpp b/task_04/src/stack.cpp index 8ca8990..fd732b6 100644 --- a/task_04/src/stack.cpp +++ b/task_04/src/stack.cpp @@ -1,21 +1,26 @@ #include "stack.hpp" -#include - -void Stack::Push(int value) { data_.push(value); } +void Stack::Push(int value) { stack_.push_back(value); } int Stack::Pop() { - auto result = data_.top(); - data_.pop(); + auto result = stack_.back(); + stack_.pop_back(); return result; } -void MinStack::Push(int value) { data_.push_back(value); } +void MinStack::Push(int value) { + stack_.push_back(value); + if (min_stack_.size() == 0 || value < min_stack_.back()) + min_stack_.push_back(value); + else + min_stack_.push_back(min_stack_.back()); +} int MinStack::Pop() { - auto result = data_.back(); - data_.pop_back(); + auto result = stack_.back(); + stack_.pop_back(); + min_stack_.pop_back(); return result; } -int MinStack::GetMin() { return *std::min_element(data_.begin(), data_.end()); } \ No newline at end of file +int MinStack::GetMin() { return min_stack_.back(); } \ No newline at end of file diff --git a/task_04/src/stack.hpp b/task_04/src/stack.hpp index 138ec40..cbcdf7f 100644 --- a/task_04/src/stack.hpp +++ b/task_04/src/stack.hpp @@ -9,7 +9,7 @@ class Stack { int Pop(); private: - std::stack data_; + std::vector stack_; }; class MinStack { @@ -19,5 +19,6 @@ class MinStack { int GetMin(); private: - std::vector data_; + std::vector stack_; + std::vector min_stack_; }; diff --git a/task_05/src/main.cpp b/task_05/src/main.cpp index 0e4393b..b4f8de6 100644 --- a/task_05/src/main.cpp +++ b/task_05/src/main.cpp @@ -1,3 +1,18 @@ #include +#include -int main() { return 0; } +#include "temperature_rise.hpp" + +int main() { + int N; + std::cin >> N; + std::vector v; + + for (int i = 0; i < N; ++i) { + int n; + std::cin >> n; + v.push_back(n); + } + std::vector v2 = TemperatureRise(v); + for (int t : v2) std::cout << t << " "; +} diff --git a/task_05/src/temperature_rise.hpp b/task_05/src/temperature_rise.hpp new file mode 100644 index 0000000..f01cc78 --- /dev/null +++ b/task_05/src/temperature_rise.hpp @@ -0,0 +1,21 @@ +#include + +std::vector TemperatureRise(std::vector v1) { + std::vector stack; + std::vector v2(v1.size(), 0); + + size_t i = 0; + while (i < v1.size()) { + if (stack.size() == 0) { + stack.push_back(i); + ++i; + } else if (v1[i] > v1[stack.back()]) { + v2[stack.back()] = i - stack.back(); + stack.pop_back(); + } else { + stack.push_back(i); + ++i; + } + } + return v2; +} \ No newline at end of file diff --git a/task_05/src/test.cpp b/task_05/src/test.cpp index ef5a86a..0ae6b41 100644 --- a/task_05/src/test.cpp +++ b/task_05/src/test.cpp @@ -1,8 +1,36 @@ #include -#include "topology_sort.hpp" +#include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "temperature_rise.hpp" + +TEST(Test, Simple) { + std::vector v1{1, 2, 3, 4, 5, 6}; + std::vector v01{1, 1, 1, 1, 1, 0}; + std::vector v2{67, 52, 42, 13, 2}; + std::vector v02{0, 0, 0, 0, 0}; + std::vector v3{52, 52, 52, 52, 52}; + std::vector v4{23, 24, 25, 21, 29, 22, 26, 23}; + std::vector v04{1, 1, 2, 1, 0, 1, 0, 0}; + std::vector v5{-13, -5, 10, 10, 0, -3, -2, 4, -10}; + std::vector v05{1, 1, 0, 0, 3, 1, 1, 0, 0}; + + ASSERT_EQ(TemperatureRise(v1), v01); // по возрастанию + ASSERT_EQ(TemperatureRise(v2), v02); // по убыванию + ASSERT_EQ(TemperatureRise(v3), v02); // одинаковые числа + ASSERT_EQ(TemperatureRise(v4), v04); // обычный + ASSERT_EQ(TemperatureRise(v5), v05); // с отрицательными числами +} + +TEST(Test, Single) { + std::vector v{52}; + std::vector v0{0}; + ASSERT_EQ(TemperatureRise(v), v0); +} + +TEST(Test, Empty) { + std::vector v{}; + std::vector v0{}; + ASSERT_EQ(TemperatureRise(v), v0); } diff --git a/task_05/src/topology_sort.cpp b/task_05/src/topology_sort.cpp deleted file mode 100644 index e53f670..0000000 --- a/task_05/src/topology_sort.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "topology_sort.hpp" diff --git a/task_05/src/topology_sort.hpp b/task_05/src/topology_sort.hpp deleted file mode 100644 index 6f70f09..0000000 --- a/task_05/src/topology_sort.hpp +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/task_06/src/get_min_cost.hpp b/task_06/src/get_min_cost.hpp new file mode 100644 index 0000000..e6faa9a --- /dev/null +++ b/task_06/src/get_min_cost.hpp @@ -0,0 +1,37 @@ +#include +#include +#include +#include + +double GetMinCost(int K, std::vector fish_cost) { + std::deque min_costs; + double min_sum = 0; + for (int i = 0; i < fish_cost.size(); ++i) { + if (min_costs.size() >= K) { + min_costs.pop_front(); + } + if (min_costs.empty()) { + min_costs.push_back(fish_cost[i]); + min_sum += fish_cost[i]; + continue; + } + min_costs.push_back(std::min(fish_cost[i], min_costs.back())); + min_sum += min_costs.back(); + // std::cout << min_sum << " "; + } + return min_sum; +} + +/* +double GetMinCost(int K, std::vector fish_cost) { + std::vector min_costs; + int left = 0; + for (int i = 0; i < fish_cost.size(); ++i) { + if (i == 0) continue; // min_costs.push_back(fish_cost[0]); + + if (fish_cost[i] <= fish_cost[i - 1]) // min_costs.back()) + // min_costs.push_back(fish_cost[i]); + else min_costs.push_back(min_costs.back()); + } +} + */ \ No newline at end of file diff --git a/task_06/src/main.cpp b/task_06/src/main.cpp index 0e4393b..2275419 100644 --- a/task_06/src/main.cpp +++ b/task_06/src/main.cpp @@ -1,3 +1,15 @@ #include +#include -int main() { return 0; } +#include "get_min_cost.hpp" + +int main() { + int n; + double K; + std::cin >> n >> K; + + std::vector costs(n); + for (int i = 0; i < n; ++i) std::cin >> costs[i]; + + std::cout << GetMinCost(K, costs) << "\n"; +} diff --git a/task_06/src/test.cpp b/task_06/src/test.cpp index 5e11617..97fce0c 100644 --- a/task_06/src/test.cpp +++ b/task_06/src/test.cpp @@ -1,6 +1,8 @@ #include -TEST(TopologySort, Simple) { +#include + +TEST(Test, Simple) { ASSERT_EQ(1, 1); // Stack [] } diff --git a/task_07/src/main.cpp b/task_07/src/main.cpp index 0e4393b..65c08b6 100644 --- a/task_07/src/main.cpp +++ b/task_07/src/main.cpp @@ -1,3 +1,20 @@ #include +#include +#include -int main() { return 0; } +using namespace std; + +int main() { + int N; + cin >> N; + vector v; + + for (int i = 0; i < N; ++i) { + int n; + cin >> n; + v.push_back(n); + } + vector v_sorted = MergeSort(v); + + for (int i = 0; i < N; ++i) cout << v_sorted[i] << " "; +} diff --git a/task_07/src/merge_sort.hpp b/task_07/src/merge_sort.hpp new file mode 100644 index 0000000..c4e63a4 --- /dev/null +++ b/task_07/src/merge_sort.hpp @@ -0,0 +1,46 @@ +#include + +using namespace std; + +vector MergingArrays(const std::vector& v1_sorted, + const std::vector& v2_sorted) { + // Слияние + vector v_sorted; + size_t ptr1 = 0, ptr2 = 0; + + while (ptr1 < v1_sorted.size() && ptr2 < v2_sorted.size()) { + if (v1_sorted[ptr1] > v2_sorted[ptr2]) { + v_sorted.push_back(v2_sorted[ptr2]); + ++ptr2; + } else { + v_sorted.push_back(v1_sorted[ptr1]); + ++ptr1; + } + } + + // Добавление оставшихся элементов + while (ptr1 < v1_sorted.size()) { + v_sorted.push_back(v1_sorted[ptr1]); + ++ptr1; + } + + while (ptr2 < v2_sorted.size()) { + v_sorted.push_back(v2_sorted[ptr2]); + ++ptr2; + } + return v_sorted; +} + +vector MergeSort(vector v) { + int n = v.size(); + if (n == 1 || n == 0) return v; + + // Деление на две части + vector v1(v.begin(), v.begin() + n / 2); + vector v2(v.begin() + n / 2, v.end()); + + vector v1_sorted = MergeSort(v1); + vector v2_sorted = MergeSort(v2); + + return MergingArrays(v1_sorted, v2_sorted); +} \ No newline at end of file diff --git a/task_07/src/test.cpp b/task_07/src/test.cpp index 5e11617..158aa1c 100644 --- a/task_07/src/test.cpp +++ b/task_07/src/test.cpp @@ -1,6 +1,32 @@ - #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include +#include + +TEST(MergeSort, Simple) { + vector v1{1, 2, 3, 4, 5}; + vector v2{5, 3, 1, 4, 2}; + vector v3{5, 3, -7, 4, -2, 0}; + vector v03{-7, -2, 0, 3, 4, 5}; + vector v4{1, 1, 42, 0, 42, 42, 52, 42, 67, 52, -52, -52, -52}; + vector v04{-52, -52, -52, 0, 1, 1, 42, 42, 42, 42, 52, 52, 67}; + vector v5{15000, 20, 17, 13, 10, 8, 5, 2, -1, -52}; + vector v05{-52, -1, 2, 5, 8, 10, 13, 17, 20, 15000}; + + ASSERT_EQ(MergeSort(v1), v1); // уже отсортированный + ASSERT_EQ(MergeSort(v2), v1); // нечетное количество элементов + ASSERT_EQ(MergeSort(v3), + v03); // четное количество элементов + отрицательные числа + ASSERT_EQ(MergeSort(v4), v04); // c повторяющимися числами + ASSERT_EQ(MergeSort(v5), v05); // обратный } + +TEST(MergeSort, Empty) { + std::vector v_empty = {}; + ASSERT_EQ(MergeSort(v_empty), v_empty); +} + +TEST(MergeSort, Single) { + std::vector v_single = {52}; + ASSERT_EQ(MergeSort(v_single), v_single); +} \ No newline at end of file diff --git a/task_08/src/get_k_element.hpp b/task_08/src/get_k_element.hpp new file mode 100644 index 0000000..3b06ba8 --- /dev/null +++ b/task_08/src/get_k_element.hpp @@ -0,0 +1,28 @@ +#include +#include + +using namespace std; + +int get_k_element(vector v, int K, int left, int right) { + int pivot = right; + + for (int i = left; i < right; ++i) { + if (pivot > i) { + if (v[i] > v[pivot]) { + swap(v[i], v[pivot]); + pivot = i; + } + } else { + if (v[i] < v[pivot]) { + swap(v[i], v[pivot]); + pivot = i; + } + } + } + + if (pivot + 1 == K) return v[pivot]; + if (pivot + 1 > K) + return get_k_element(v, K, left, pivot - 1); + else + return get_k_element(v, K, pivot + 1, right); +} \ No newline at end of file diff --git a/task_08/src/main.cpp b/task_08/src/main.cpp index 0e4393b..9534489 100644 --- a/task_08/src/main.cpp +++ b/task_08/src/main.cpp @@ -1,3 +1,22 @@ #include +#include -int main() { return 0; } +#include "get_k_element.hpp" + +using namespace std; + +int main() { + int N, K; + cin >> N >> K; + + vector v; + + for (int i = 0; i < N; ++i) { + int n; + cin >> n; + v.push_back(n); + } + + int left{0}, right(N - 1); + cout << get_k_element(v, K, left, right) << endl; +} diff --git a/task_08/src/test.cpp b/task_08/src/test.cpp index 5e11617..2854e00 100644 --- a/task_08/src/test.cpp +++ b/task_08/src/test.cpp @@ -1,6 +1,82 @@ - #include +#include +#include + +using namespace std; + TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] + vector v1{0, 1}; + vector v2{0, 0, 0, 1, 1}; + vector v3{0, 0, 0, 0, 0, 1}; + vector v4{0, 1, 1, 1, 1}; + vector v5{0, 0, 1, 1, 1, 1}; + + ASSERT_EQ(get_k_element(v1, 1, 0, v1.size() - 1), 0); + ASSERT_EQ(get_k_element(v2, 1, 0, v2.size() - 1), 0); + ASSERT_EQ(get_k_element(v3, 1, 0, v3.size() - 1), 0); + ASSERT_EQ(get_k_element(v4, 1, 0, v4.size() - 1), 0); + ASSERT_EQ(get_k_element(v5, 1, 0, v5.size() - 1), 0); + + ASSERT_EQ(get_k_element(v1, 2, 0, v1.size() - 1), 1); + ASSERT_EQ(get_k_element(v2, 5, 0, v2.size() - 1), 1); + ASSERT_EQ(get_k_element(v3, 6, 0, v3.size() - 1), 1); + + ASSERT_EQ(get_k_element(v2, 3, 0, v2.size() - 1), 0); + ASSERT_EQ(get_k_element(v4, 3, 0, v4.size() - 1), 1); + ASSERT_EQ(get_k_element(v5, 4, 0, v5.size() - 1), 1); +} + +TEST(Test, DifferentNumbers) { + // положительные числа + vector v1{7, 10, 4, 3, 20}; + ASSERT_EQ(get_k_element(v1, 1, 0, v1.size() - 1), 3); + ASSERT_EQ(get_k_element(v1, 3, 0, v1.size() - 1), 7); + ASSERT_EQ(get_k_element(v1, 5, 0, v1.size() - 1), 20); + + // отрицательные числа + vector v2{-5, -2, -8, -1, -3}; + ASSERT_EQ(get_k_element(v2, 1, 0, v2.size() - 1), -8); + ASSERT_EQ(get_k_element(v2, 3, 0, v2.size() - 1), -3); + ASSERT_EQ(get_k_element(v2, 5, 0, v2.size() - 1), -1); + + // положительные и отрицательные + vector v3{-10, 5, -3, 8, 0, -7, 2}; + ASSERT_EQ(get_k_element(v3, 1, 0, v3.size() - 1), -10); + ASSERT_EQ(get_k_element(v3, 4, 0, v3.size() - 1), 0); + ASSERT_EQ(get_k_element(v3, 7, 0, v3.size() - 1), 8); + + // повторяющиеся элементы + vector v4{5, 5, 5, 1, 1, 9, 9, 9, 9}; + ASSERT_EQ(get_k_element(v4, 1, 0, v4.size() - 1), 1); + ASSERT_EQ(get_k_element(v4, 3, 0, v4.size() - 1), 5); + ASSERT_EQ(get_k_element(v4, 6, 0, v4.size() - 1), 9); + ASSERT_EQ(get_k_element(v4, 9, 0, v4.size() - 1), 9); } + +TEST(Test, TooSimple) { + // один элемент + vector v1{42}; + ASSERT_EQ(get_k_element(v1, 1, 0, 0), 42); + + // два элемента + vector v2{100, 200}; + ASSERT_EQ(get_k_element(v2, 1, 0, 1), 100); + ASSERT_EQ(get_k_element(v2, 2, 0, 1), 200); + + // два одинаковых элемента + vector v3{7, 7}; + ASSERT_EQ(get_k_element(v3, 1, 0, 1), 7); + ASSERT_EQ(get_k_element(v3, 2, 0, 1), 7); + + // одинаковые + vector v4{3, 3, 3, 3, 3}; + for (int k = 1; k <= 5; k++) { + ASSERT_EQ(get_k_element(v4, k, 0, v4.size() - 1), 3); + } + + vector v5{-1, 0, -1, 0, -2}; + ASSERT_EQ(get_k_element(v5, 1, 0, v5.size() - 1), -2); + ASSERT_EQ(get_k_element(v5, 3, 0, v5.size() - 1), -1); + ASSERT_EQ(get_k_element(v5, 5, 0, v5.size() - 1), 0); +} \ No newline at end of file diff --git a/task_09/src/splay_tree.cpp b/task_09/src/splay_tree.cpp new file mode 100644 index 0000000..c7889c6 --- /dev/null +++ b/task_09/src/splay_tree.cpp @@ -0,0 +1,164 @@ +#include "splay_tree.hpp" + +#include + +void SplayTree::RotateLeft(Node* n) { + Node* m = n->right; + if (!m) return; + + Node* parent = n->parent; + n->right = m->left; + if (m->left) m->left->parent = n; + + m->left = n; + n->parent = m; + m->parent = parent; + + if (parent) { + if (parent->left == n) + parent->left = m; + else + parent->right = m; + } else + root = m; +} + +void SplayTree::RotateRight(Node* n) { + Node* m = n->left; + if (!m) return; + + Node* parent = n->parent; + n->left = m->right; + if (m->right) m->right->parent = n; + + m->right = n; + n->parent = m; + m->parent = parent; + + if (parent) { + if (parent->left == n) + parent->left = m; + else + parent->right = m; + } else + root = m; +} + +void SplayTree::Splay(Node* n) { + if (!n->parent) return; + + if (!n->parent->parent) { + if (n->parent->left == n) + RotateRight(n->parent); + else + RotateLeft(n->parent); + return; + } + if (n->parent->right == n) { + if (n->parent->parent->right == n->parent) { + RotateLeft(n->parent->parent); + RotateLeft(n->parent); + } else { + RotateLeft(n->parent); + RotateRight(n->parent); + } + } else { + if (n->parent->parent->left == n->parent) { + RotateRight(n->parent->parent); + RotateRight(n->parent); + } else { + RotateRight(n->parent); + RotateLeft(n->parent); + } + } + Splay(n); +} + +void SplayTree::Insert(int key) { + if (!root) { + root = new Node(key); + return; + } + + Node* current = root; + Node* parent = nullptr; + + while (current) { + parent = current; + if (key <= current->key) + current = current->left; + else + current = current->right; + } + + Node* new_n = new Node(key); + new_n->parent = parent; + + if (key <= parent->key) + parent->left = new_n; + else + parent->right = new_n; + + Splay(new_n); +} + +bool SplayTree::Find(int key) { + if (!root) return false; + + Node* current = root; + Node* last = nullptr; + + while (current) { + last = current; + if (key == current->key) { + Splay(current); + return true; + } else if (key < current->key) + current = current->left; + else + current = current->right; + } + if (last) Splay(last); + return false; +} + +void SplayTree::Remove(int key) { + if (Find(key)) { + Node* n = root; + + Node* left_tree = root->left; + Node* right_tree = root->right; + + if (!left_tree) { + root = right_tree; + if (right_tree) right_tree->parent = nullptr; + delete n; + return; + } + if (!right_tree) { + root = left_tree; + if (left_tree) left_tree->parent = nullptr; + delete n; + return; + } + + Node* current = right_tree; + Node* last = nullptr; + + while (current) { + last = current; + current = current->left; + } + + Splay(last); + + if (last->left) last->left->parent = nullptr; + last->left = nullptr; + + root = last; + last->left = left_tree; + left_tree->parent = last; + + delete n; + } +} \ No newline at end of file diff --git a/task_09/src/splay_tree.hpp b/task_09/src/splay_tree.hpp new file mode 100644 index 0000000..b0cd735 --- /dev/null +++ b/task_09/src/splay_tree.hpp @@ -0,0 +1,25 @@ +#pragma once + +struct Node { + Node(const int& key) + : key(key), left(nullptr), right(nullptr), parent(nullptr){}; + + Node* left; + Node* right; + Node* parent; + int key; +}; + +struct SplayTree { + void Insert(int key); // вставка ключа + bool Find(int key); // поиск ключа + void Remove(int key); // удаление ключа + + private: + Node* root{nullptr}; + + void RotateRight(Node* n); + void RotateLeft(Node* n); + + void Splay(Node* n); +}; \ No newline at end of file diff --git a/task_09/src/test.cpp b/task_09/src/test.cpp index 5e11617..7132d82 100644 --- a/task_09/src/test.cpp +++ b/task_09/src/test.cpp @@ -1,6 +1,98 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "splay_tree.hpp" + +TEST(Test, Simple) { + SplayTree tree; + + // Поиск ключа в пустом дереве + ASSERT_EQ(tree.Find(52), false); + ASSERT_EQ(tree.Find(0), false); + ASSERT_EQ(tree.Find(-42), false); + + tree.Remove(67); + ASSERT_EQ(tree.Find(67), false); // tree [] + + tree.Insert(52); + ASSERT_EQ(tree.Find(52), true); // tree [52] + tree.Remove(52); + ASSERT_EQ(tree.Find(52), false); // tree [] + + tree.Insert(52); + tree.Insert(0); + tree.Insert(67); + tree.Insert(42); + tree.Insert(-67); + tree.Insert(69); + // tree [52, 0, 67, 42, -67, 69] + + // Значения, которые есть в дереве + ASSERT_EQ(tree.Find(52), true); + ASSERT_EQ(tree.Find(-67), true); + ASSERT_EQ(tree.Find(0), true); + ASSERT_EQ(tree.Find(67), true); + ASSERT_EQ(tree.Find(42), true); + ASSERT_EQ(tree.Find(69), true); + + // Значения, которых нет в дереве + ASSERT_EQ(tree.Find(4), false); + ASSERT_EQ(tree.Find(17), false); + ASSERT_EQ(tree.Find(-34), false); + ASSERT_EQ(tree.Find(55), false); + ASSERT_EQ(tree.Find(95), false); + ASSERT_EQ(tree.Find(-56), false); + + tree.Remove(52); + + // tree [0, 67, 42, -67, 69] + ASSERT_EQ(tree.Find(52), false); + ASSERT_EQ(tree.Find(-67), true); + ASSERT_EQ(tree.Find(0), true); + ASSERT_EQ(tree.Find(67), true); + + tree.Remove(42); + tree.Remove(-67); + tree.Remove(69); + tree.Remove(42); + tree.Remove(0); + tree.Remove(67); + + // tree [] + ASSERT_EQ(tree.Find(-67), false); + ASSERT_EQ(tree.Find(0), false); + ASSERT_EQ(tree.Find(67), false); +} + +TEST(Test, ReapitingKeys) { + SplayTree tree; + + tree.Insert(0); + tree.Insert(67); + tree.Insert(42); + tree.Insert(-67); + tree.Insert(69); + tree.Insert(8); + tree.Insert(8); + tree.Insert(8); + + // tree [0, 67, 42, -67, 69, 8, 8] + + ASSERT_EQ(tree.Find(8), true); + ASSERT_EQ(tree.Find(-67), true); + + tree.Remove(8); + + // tree [0, 67, 42, -67, 69, 8, 8] + ASSERT_EQ(tree.Find(8), true); + + tree.Remove(8); + + // tree [0, 67, 42, -67, 69, 8] + ASSERT_EQ(tree.Find(8), true); + + tree.Remove(8); + + // tree [0, 67, 42, -67, 69] + ASSERT_EQ(tree.Find(8), false); } diff --git a/task_10/src/hash_table.cpp b/task_10/src/hash_table.cpp new file mode 100644 index 0000000..8448515 --- /dev/null +++ b/task_10/src/hash_table.cpp @@ -0,0 +1,52 @@ +#include "hash_table.hpp" + +#include + +HashTable::HashTable(size_t size) : data(size) {} + +void HashTable::Insert(int key, int value) { + int hash = std::hash{}(key) % data.size(); + Node n{key, value}; + + auto& values = data[hash]; + for (auto it = values.begin(); it != values.end(); ++it) { + if (it->key == key) { + it->value = value; + return; + } + } + values.push_front(n); +} + +void HashTable::Remove(int key) { + int hash = std::hash{}(key) % data.size(); + auto& values = data[hash]; + + auto previous = values.before_begin(); + + for (auto current = values.begin(); current != values.end(); ++current) { + if (current->key == key) { + values.erase_after(previous); + return; + } + previous = current; + } +} + +std::optional HashTable::Get(int key) { + int hash = std::hash{}(key) % data.size(); + auto& values = data[hash]; + for (const auto& node : values) { + if (node.key == key) return node.value; + } + return {}; +} + +bool HashTable::Contains(int key) { + int hash = std::hash{}(key) % data.size(); + auto& values = data[hash]; + for (const auto& node : values) { + if (node.key == key) return true; + } + return false; +} \ No newline at end of file diff --git a/task_10/src/hash_table.hpp b/task_10/src/hash_table.hpp new file mode 100644 index 0000000..77d2f58 --- /dev/null +++ b/task_10/src/hash_table.hpp @@ -0,0 +1,21 @@ +#include +#include +#include + +class HashTable { + public: + HashTable(size_t size = 10); + + void Insert(int key, int value); // вставка пары ключ-значение + std::optional Get(int key); // получение значения по ключу + void Remove(int key); // удаление по ключу + bool Contains(int key); // проверка наличия ключа + + private: + struct Node { + int key; + int value; + }; + + std::vector> data; +}; diff --git a/task_10/src/test.cpp b/task_10/src/test.cpp index 5e11617..b6be342 100644 --- a/task_10/src/test.cpp +++ b/task_10/src/test.cpp @@ -1,6 +1,81 @@ - #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "hash_table.hpp" + +TEST(Test, Simple) { + HashTable table; + + ASSERT_EQ(table.Get(52), std::nullopt); + ASSERT_EQ(table.Contains(52), false); + + table.Remove(52); + table.Insert(0, 52); + ASSERT_EQ(table.Get(0), 52); + ASSERT_EQ(table.Contains(0), true); +} + +TEST(Test, UpdateValue) { + HashTable table; + + table.Insert(1, 42); + ASSERT_EQ(table.Get(1), 42); + + table.Insert(1, 52); // обновляем значение + ASSERT_EQ(table.Get(1), 52); + ASSERT_EQ(table.Contains(1), true); } + +TEST(Test, RemoveKey) { + HashTable table; + + table.Insert(1, 67); + table.Insert(2, 200); + table.Insert(3, 0); + + ASSERT_EQ(table.Contains(2), true); + table.Remove(2); + ASSERT_EQ(table.Contains(2), false); + ASSERT_EQ(table.Get(2), std::nullopt); + + ASSERT_EQ(table.Get(1), 67); + ASSERT_EQ(table.Get(3), 0); +} + +TEST(Test, Collisions) { + HashTable table(5); // маленький размер для коллизий + + // 1 % 5 = 1, 6 % 5 = 1, 11 % 5 = 1 + table.Insert(1, 52); + table.Insert(6, 42); + table.Insert(11, 67); + + ASSERT_EQ(table.Get(1), 52); + ASSERT_EQ(table.Get(6), 42); + ASSERT_EQ(table.Get(11), 67); + ASSERT_EQ(table.Contains(1), true); + ASSERT_EQ(table.Contains(6), true); + ASSERT_EQ(table.Contains(11), true); + + table.Remove(6); + + ASSERT_EQ(table.Contains(6), false); + ASSERT_EQ(table.Get(6), std::nullopt); + ASSERT_EQ(table.Get(1), 52); + ASSERT_EQ(table.Get(11), 67); +} + +TEST(Test, NegativeKeys) { + HashTable table; + + table.Insert(-5, 42); + table.Insert(-10, 52); + + ASSERT_EQ(table.Get(-5), 42); + ASSERT_EQ(table.Get(-10), 52); + ASSERT_EQ(table.Contains(-5), true); + + table.Remove(-10); + ASSERT_EQ(table.Contains(-10), false); + ASSERT_EQ(table.Get(-10), std::nullopt); + ASSERT_EQ(table.Get(-5), 42); +} \ No newline at end of file diff --git a/task_12/src/exchange_of_coins.hpp b/task_12/src/exchange_of_coins.hpp new file mode 100644 index 0000000..9f34075 --- /dev/null +++ b/task_12/src/exchange_of_coins.hpp @@ -0,0 +1,25 @@ +#include +#include + +int MinNumberOfCoins(int sum, std::vector denominations) { + int n = denominations.size(); + + if (sum < 0) return -1; + + std::vector dp( + sum + + 1); // i-ый элемент - минимальное количество монет, нужное для суммы i + dp[0] = 0; + + for (int i = 1; i < sum + 1; ++i) { + dp[i] = 2e9; + for (int coin : denominations) { + if (coin <= 0) continue; // берем только положительные номиналы + if (i - coin >= 0) { + dp[i] = std::min(dp[i], dp[i - coin] + 1); + } + } + } + if (dp[sum] < 2e9) return dp[sum]; + return -1; +} \ No newline at end of file diff --git a/task_12/src/main.cpp b/task_12/src/main.cpp index 0e4393b..94a3e72 100644 --- a/task_12/src/main.cpp +++ b/task_12/src/main.cpp @@ -1,3 +1,17 @@ #include +#include -int main() { return 0; } +#include "exchange_of_coins.hpp" + +int main() { + int sum; + std::cin >> sum; + + int n; + std::cin >> n; + + std::vector denominations(n); + for (int i = 0; i < n; ++i) std::cin >> denominations[i]; + + std::cout << MinNumberOfCoins(sum, denominations) << "\n"; +} diff --git a/task_12/src/test.cpp b/task_12/src/test.cpp index 869094d..63f1e32 100644 --- a/task_12/src/test.cpp +++ b/task_12/src/test.cpp @@ -1,4 +1,51 @@ - #include -TEST(TopologySort, Simple) { ASSERT_EQ(1, 1); } +#include "exchange_of_coins.hpp" + +TEST(Test, Simple) { + ASSERT_EQ(MinNumberOfCoins(15, {1, 5, 10}), 2); // 10+5 + ASSERT_EQ(MinNumberOfCoins(0, {1, 2, 3}), 0); // нулевая сумма + ASSERT_EQ(MinNumberOfCoins(7, {2, 4, 6}), -1); // нет + ASSERT_EQ(MinNumberOfCoins(30, {10, 20, 30}), 1); // 30 + ASSERT_EQ(MinNumberOfCoins(12, {1, 3, 5}), 4); // 5+5+1+1 + ASSERT_EQ(MinNumberOfCoins(100, {25, 10, 5, 1}), 4); // 25+25+25+25 + ASSERT_EQ(MinNumberOfCoins(999999, {1}), 999999); +} + +TEST(Test, SingleCoin) { + // Одна монета + ASSERT_EQ(MinNumberOfCoins(5, {5}), 1); // 5 + ASSERT_EQ(MinNumberOfCoins(10, {5}), 2); // 5+5 + ASSERT_EQ(MinNumberOfCoins(3, {5}), -1); // нет +} + +TEST(Test, NegativesAndZero) { + // С отрицательными номиналами и нулём + std::vector v = {-42, -52, 10, 10, 0, -3, -2, 4, -10}; + ASSERT_EQ(MinNumberOfCoins(20, v), 2); // 10+10 + ASSERT_EQ(MinNumberOfCoins(4, v), 1); // 4 + ASSERT_EQ(MinNumberOfCoins(3, v), -1); // нет +} + +TEST(Test, Empty) { + // Пустой вектор номиналов + std::vector empty; + ASSERT_EQ(MinNumberOfCoins(52, empty), -1); + ASSERT_EQ(MinNumberOfCoins(0, empty), 0); +} + +TEST(Test, AllSame) { + // Все номиналы одинаковые + std::vector v = {52, 52, 52, 52, 52}; + ASSERT_EQ(MinNumberOfCoins(104, v), 2); // 52+52 + ASSERT_EQ(MinNumberOfCoins(53, v), -1); // нет + ASSERT_EQ(MinNumberOfCoins(0, v), 0); +} + +TEST(Test, EdgeCases) { + // Граничные случаи + ASSERT_EQ(MinNumberOfCoins(1, {2, 3, 5}), + -1); // минимальная монета больше суммы + ASSERT_EQ(MinNumberOfCoins(1000000, {999983}), -1); + ASSERT_EQ(MinNumberOfCoins(1, {1}), 1); +}