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..6a9c418 --- /dev/null +++ b/task_02/src/get_border_index.hpp @@ -0,0 +1,15 @@ +#include + +int GetBorderIndex(const std::vector &v) { + int left = 0, right = v.size() - 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..88d59c5 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(std::cin, line1); + getline(std::cin, line2); + + N = stoi(line1); + + std::istringstream is(line2); + int x; + while (is >> x) v.push_back(x); + + std::cout << GetBorderIndex(v) << std::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..002a58c 100644 --- a/task_03/src/test.cpp +++ b/task_03/src/test.cpp @@ -1,4 +1,55 @@ - #include -TEST(TopologySort, Simple) { ASSERT_EQ(1, 1); } +#include + +#include "get_combinations.hpp" + +TEST(Test, Single) { + // Одна цифра + std::vector empty{}; + std::vector expected2{"a", "b", "c"}; + std::vector expected3{"d", "e", "f"}; + std::vector expected4{"g", "h", "i"}; + std::vector expected5{"j", "k", "l"}; + std::vector expected6{"m", "n", "o"}; + std::vector expected7{"p", "q", "r", "s"}; + std::vector expected8{"t", "u", "v"}; + std::vector expected9{"w", "x", "y", "z"}; + + ASSERT_EQ(GetCombinations("0"), empty); + ASSERT_EQ(GetCombinations("1"), empty); + ASSERT_EQ(GetCombinations("2"), expected2); + ASSERT_EQ(GetCombinations("3"), expected3); + ASSERT_EQ(GetCombinations("4"), expected4); + ASSERT_EQ(GetCombinations("5"), expected5); + ASSERT_EQ(GetCombinations("6"), expected6); + ASSERT_EQ(GetCombinations("7"), expected7); + ASSERT_EQ(GetCombinations("8"), expected8); + ASSERT_EQ(GetCombinations("9"), expected9); +} + +TEST(Test, TwoDigits) { + // Две цифры + std::vector expected1{"ad", "ae", "af", "bd", "be", + "bf", "cd", "ce", "cf"}; + std::vector expected2{"pw", "px", "py", "pz", "qw", "qx", + "qy", "qz", "rw", "rx", "ry", "rz", + "sw", "sx", "sy", "sz"}; + ASSERT_EQ(GetCombinations("23"), expected1); + ASSERT_EQ(GetCombinations("79"), expected2); +} + +TEST(Test, ThreeDigits) { + // Три цифры + std::vector expected{ + "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"), expected); +} + +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..0d99bcf 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_.empty() || 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..e6a9aaa --- /dev/null +++ b/task_06/src/get_min_cost.hpp @@ -0,0 +1,22 @@ +#include +#include + +double GetMinCost(int K, std::vector fish_cost) { + double sum = 0.0; + std::deque rising_costs; // индексы с возрастающими ценами + + for (int i = 0; i < fish_cost.size(); ++i) { + if (!rising_costs.empty() && rising_costs.front() < i - K + 1) + rising_costs.pop_front(); + + while (!rising_costs.empty() && + fish_cost[rising_costs.back()] > fish_cost[i]) { + rising_costs.pop_back(); + } + rising_costs.push_back(i); + + sum += fish_cost[rising_costs.front()]; + } + + return sum; +} \ 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..e8c3374 100644 --- a/task_06/src/test.cpp +++ b/task_06/src/test.cpp @@ -1,6 +1,72 @@ - #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include + +TEST(Test, Simple) { + std::vector v1{2, 8, 1, 5}; + ASSERT_DOUBLE_EQ(GetMinCost(3, v1), 6); + + std::vector v2{5, 5, 5, 2, 2, 2}; + ASSERT_DOUBLE_EQ(GetMinCost(3, v2), 21); + + std::vector v3{2, 4, 6, 8, 10, 8, 6, 4, 2}; + ASSERT_DOUBLE_EQ(GetMinCost(3, v3), 36); // 2+2+2+4+6+6+8+4+2 +} + +TEST(Test, SingleDay) { + std::vector v1{5}; + ASSERT_DOUBLE_EQ(GetMinCost(1, v1), 5.0); +} + +TEST(Test, TwoDays) { + std::vector v1{5, 3}; + ASSERT_DOUBLE_EQ(GetMinCost(1, v1), 8.0); // 5+3 + ASSERT_DOUBLE_EQ(GetMinCost(2, v1), 8.0); // 5+3 +} +TEST(Test, ThreeDays) { + std::vector v1{5, 3, 4}; + ASSERT_DOUBLE_EQ(GetMinCost(1, v1), 12.0); // 5+3+4 + ASSERT_DOUBLE_EQ(GetMinCost(2, v1), 11.0); // 5+3+3 + ASSERT_DOUBLE_EQ(GetMinCost(3, v1), 11.0); // 5+3+3 +} + +TEST(Test, IncreasingPrices) { + std::vector v1{1, 2, 3, 4, 5}; + ASSERT_DOUBLE_EQ(GetMinCost(2, v1), 11.0); // 1 + 1 + 2 + 3 + 4 +} + +TEST(Test, DecreasingPrices) { + std::vector v1{5, 4, 3, 2, 1}; + ASSERT_DOUBLE_EQ(GetMinCost(2, v1), 15.0); +} + +TEST(Test, AllSamePrices) { + std::vector v1{3, 3, 3, 3}; + ASSERT_DOUBLE_EQ(GetMinCost(2, v1), 12.0); // 3+3+3+3 +} + +TEST(Test, KBiggerN) { + std::vector v1{10, 5, 7}; + ASSERT_DOUBLE_EQ(GetMinCost(5, v1), 20); // 10+5+5 +} + +TEST(Test, KEqualsN) { + std::vector v1{8, 3, 6, 2, 9}; + ASSERT_DOUBLE_EQ(GetMinCost(5, v1), 18.0); // 8+3+3+2+2 +} + +TEST(Test, KEquals1) { + std::vector v1{4, 1, 3, 2, 5}; + ASSERT_DOUBLE_EQ(GetMinCost(1, v1), 15.0); // 4+1+3+2+5 } + +TEST(Test, FloatingPrices) { + std::vector v1{2.5, 1.8, 3.2, 2.1}; + ASSERT_DOUBLE_EQ(GetMinCost(2, v1), 8.2); // 2.5 + 1.8 + 1.8 + 2.1 + ASSERT_DOUBLE_EQ(GetMinCost(3, v1), 7.9); // 2.5 + 1.8 + 1.8 + 1.8 +} + +TEST(Test, LargeK) { + std::vector v1{100, 1, 100, 1, 100}; + ASSERT_DOUBLE_EQ(GetMinCost(100, v1), 104); // 100+1+1+1+1 +} \ No newline at end of file diff --git a/task_07/src/main.cpp b/task_07/src/main.cpp index 0e4393b..73cfec8 100644 --- a/task_07/src/main.cpp +++ b/task_07/src/main.cpp @@ -1,3 +1,18 @@ #include +#include +#include -int main() { return 0; } +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 v_sorted = MergeSort(v); + + for (int i = 0; i < N; ++i) std::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..8780709 --- /dev/null +++ b/task_07/src/merge_sort.hpp @@ -0,0 +1,44 @@ +#include + +std::vector MergingArrays(const std::vector& v1_sorted, + const std::vector& v2_sorted) { + // Слияние + std::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; +} + +std::vector MergeSort(std::vector v) { + int n = v.size(); + if (n == 1 || n == 0) return v; + + // Деление на две части + std::vector v1(v.begin(), v.begin() + n / 2); + std::vector v2(v.begin() + n / 2, v.end()); + + std::vector v1_sorted = MergeSort(v1); + std::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..2564a11 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) { + std::vector v1{1, 2, 3, 4, 5}; + std::vector v2{5, 3, 1, 4, 2}; + std::vector v3{5, 3, -7, 4, -2, 0}; + std::vector v03{-7, -2, 0, 3, 4, 5}; + std::vector v4{1, 1, 42, 0, 42, 42, 52, 42, 67, 52, -52, -52, -52}; + std::vector v04{-52, -52, -52, 0, 1, 1, 42, 42, 42, 42, 52, 52, 67}; + std::vector v5{15000, 20, 17, 13, 10, 8, 5, 2, -1, -52}; + std::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/main.cpp b/task_08/src/main.cpp index 0e4393b..588aab7 100644 --- a/task_08/src/main.cpp +++ b/task_08/src/main.cpp @@ -1,3 +1,16 @@ #include +#include -int main() { return 0; } +#include "order_statistic.hpp" + +int main() { + int n, K; + std::cin >> n >> K; + + std::vector array(n); + + for (int i = 0; i < n; ++i) std::cin >> array[i]; + + int left{0}, right(n - 1); + std::cout << OrderStatistic(array, K, left, right) << "\n"; +} diff --git a/task_08/src/order_statistic.hpp b/task_08/src/order_statistic.hpp new file mode 100644 index 0000000..ec56c77 --- /dev/null +++ b/task_08/src/order_statistic.hpp @@ -0,0 +1,22 @@ +#include + +int OrderStatistic(std::vector array, int K, int left, int right) { + if (left >= right) return array[left]; + int pivot = right; + int border = left; + + for (int i = left; i < right; ++i) { + if (array[i] <= array[pivot]) { + std::swap(array[i], array[border]); + ++border; + } + } + std::swap(array[border], array[pivot]); + pivot = border; + + if (pivot + 1 == K) return array[pivot]; + if (pivot + 1 > K) + return OrderStatistic(array, K, left, pivot - 1); + else + return OrderStatistic(array, K, pivot + 1, right); +} \ No newline at end of file diff --git a/task_08/src/test.cpp b/task_08/src/test.cpp index 5e11617..65875e2 100644 --- a/task_08/src/test.cpp +++ b/task_08/src/test.cpp @@ -1,6 +1,81 @@ - #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include + +#include "order_statistic.hpp" + +TEST(Test, Simple) { + 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}; + + ASSERT_EQ(OrderStatistic(v1, 1, 0, v1.size() - 1), 0); + ASSERT_EQ(OrderStatistic(v2, 1, 0, v2.size() - 1), 0); + ASSERT_EQ(OrderStatistic(v3, 1, 0, v3.size() - 1), 0); + ASSERT_EQ(OrderStatistic(v4, 1, 0, v4.size() - 1), 0); + ASSERT_EQ(OrderStatistic(v5, 1, 0, v5.size() - 1), 0); + + ASSERT_EQ(OrderStatistic(v1, 2, 0, v1.size() - 1), 1); + ASSERT_EQ(OrderStatistic(v2, 5, 0, v2.size() - 1), 1); + ASSERT_EQ(OrderStatistic(v3, 6, 0, v3.size() - 1), 1); + + ASSERT_EQ(OrderStatistic(v2, 3, 0, v2.size() - 1), 0); + ASSERT_EQ(OrderStatistic(v4, 3, 0, v4.size() - 1), 1); + ASSERT_EQ(OrderStatistic(v5, 4, 0, v5.size() - 1), 1); +} + +TEST(Test, DifferentNumbers) { + // положительные числа + std::vector v1{7, 10, 4, 3, 20}; + ASSERT_EQ(OrderStatistic(v1, 1, 0, v1.size() - 1), 3); + ASSERT_EQ(OrderStatistic(v1, 3, 0, v1.size() - 1), 7); + ASSERT_EQ(OrderStatistic(v1, 5, 0, v1.size() - 1), 20); + + // отрицательные числа + std::vector v2{-5, -2, -8, -1, -3}; + ASSERT_EQ(OrderStatistic(v2, 1, 0, v2.size() - 1), -8); + ASSERT_EQ(OrderStatistic(v2, 3, 0, v2.size() - 1), -3); + ASSERT_EQ(OrderStatistic(v2, 5, 0, v2.size() - 1), -1); + + // положительные и отрицательные + std::vector v3{-10, 5, -3, 8, 0, -7, 2}; + ASSERT_EQ(OrderStatistic(v3, 1, 0, v3.size() - 1), -10); + ASSERT_EQ(OrderStatistic(v3, 4, 0, v3.size() - 1), 0); + ASSERT_EQ(OrderStatistic(v3, 7, 0, v3.size() - 1), 8); + + // повторяющиеся элементы + std::vector v4{5, 5, 5, 1, 1, 9, 9, 9, 9}; + ASSERT_EQ(OrderStatistic(v4, 1, 0, v4.size() - 1), 1); + ASSERT_EQ(OrderStatistic(v4, 3, 0, v4.size() - 1), 5); + ASSERT_EQ(OrderStatistic(v4, 6, 0, v4.size() - 1), 9); + ASSERT_EQ(OrderStatistic(v4, 9, 0, v4.size() - 1), 9); } + +TEST(Test, TooSimple) { + // один элемент + std::vector v1{42}; + ASSERT_EQ(OrderStatistic(v1, 1, 0, 0), 42); + + // два элемента + std::vector v2{100, 200}; + ASSERT_EQ(OrderStatistic(v2, 1, 0, 1), 100); + ASSERT_EQ(OrderStatistic(v2, 2, 0, 1), 200); + + // два одинаковых элемента + std::vector v3{7, 7}; + ASSERT_EQ(OrderStatistic(v3, 1, 0, 1), 7); + ASSERT_EQ(OrderStatistic(v3, 2, 0, 1), 7); + + // одинаковые + std::vector v4{3, 3, 3, 3, 3}; + for (int k = 1; k <= 5; k++) { + ASSERT_EQ(OrderStatistic(v4, k, 0, v4.size() - 1), 3); + } + + std::vector v5{-1, 0, -1, 0, -2}; + ASSERT_EQ(OrderStatistic(v5, 1, 0, v5.size() - 1), -2); + ASSERT_EQ(OrderStatistic(v5, 3, 0, v5.size() - 1), -1); + ASSERT_EQ(OrderStatistic(v5, 5, 0, v5.size() - 1), 0); +} \ No newline at end of file diff --git a/task_08/tests/err.in b/task_08/tests/err.in new file mode 100644 index 0000000..e6dda23 --- /dev/null +++ b/task_08/tests/err.in @@ -0,0 +1,2 @@ +4 2 +2 3 -5 -4 \ No newline at end of file diff --git a/task_08/tests/err.out b/task_08/tests/err.out new file mode 100644 index 0000000..03d0e45 --- /dev/null +++ b/task_08/tests/err.out @@ -0,0 +1 @@ +-4 \ 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..3b4de72 --- /dev/null +++ b/task_09/src/splay_tree.cpp @@ -0,0 +1,162 @@ +#include "splay_tree.hpp" + +void SplayTree::RotateLeft(Node* node) { + Node* node_right = node->right; + if (!node_right) return; + + Node* parent = node->parent; + node->right = node_right->left; + if (node_right->left) node_right->left->parent = node; + + node_right->left = node; + node->parent = node_right; + node_right->parent = parent; + + if (parent) { + if (parent->left == node) + parent->left = node_right; + else + parent->right = node_right; + } else + root = node_right; +} + +void SplayTree::RotateRight(Node* node) { + Node* node_left = node->left; + if (!node_left) return; + + Node* parent = node->parent; + node->left = node_left->right; + if (node_left->right) node_left->right->parent = node; + + node_left->right = node; + node->parent = node_left; + node_left->parent = parent; + + if (parent) { + if (parent->left == node) + parent->left = node_left; + else + parent->right = node_left; + } else + root = node_left; +} + +void SplayTree::Splay(Node* node) { + if (!node->parent) return; + + if (!node->parent->parent) { + if (node->parent->left == node) + RotateRight(node->parent); + else + RotateLeft(node->parent); + return; + } + if (node->parent->right == node) { + if (node->parent->parent->right == node->parent) { + RotateLeft(node->parent->parent); + RotateLeft(node->parent); + } else { + RotateLeft(node->parent); + RotateRight(node->parent); + } + } else { + if (node->parent->parent->left == node->parent) { + RotateRight(node->parent->parent); + RotateRight(node->parent); + } else { + RotateRight(node->parent); + RotateLeft(node->parent); + } + } + Splay(node); +} + +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_node = new Node(key); + new_node->parent = parent; + + if (key <= parent->key) + parent->left = new_node; + else + parent->right = new_node; + + Splay(new_node); +} + +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* node = 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 node; + return; + } + if (!right_tree) { + root = left_tree; + if (left_tree) left_tree->parent = nullptr; + delete node; + 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 node; + } +} \ 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_11/src/main.cpp b/task_11/src/main.cpp index 0e4393b..6f65f30 100644 --- a/task_11/src/main.cpp +++ b/task_11/src/main.cpp @@ -1,3 +1,13 @@ #include +#include -int main() { return 0; } +#include "substring_search.hpp" + +int main() { + std::string text, substring; + + std::getline(std::cin, text); + std::getline(std::cin, substring); + + std::cout << SubstringSearch(text, substring) << "\n"; +} diff --git a/task_11/src/substring_search.hpp b/task_11/src/substring_search.hpp new file mode 100644 index 0000000..ba220fb --- /dev/null +++ b/task_11/src/substring_search.hpp @@ -0,0 +1,23 @@ +#include + +int SubstringSearch(const std::string& string, const std::string& substring) { + if (substring.size() > string.size()) return -1; + + int letters[256] = {0}; + for (char c : substring) ++letters[c]; + + int need = substring.length(); + + for (int i = 0; i < string.length(); ++i) { + --letters[string[i]]; + if (letters[string[i]] >= 0) --need; + if (letters[string[i]] < 0 && need + 1 <= substring.length()) { + ++need; + ++letters[string[i]]; + } + + if (need == 0) return i - substring.length() + 2; + } + + return -1; +} \ No newline at end of file diff --git a/task_11/src/test.cpp b/task_11/src/test.cpp index 869094d..540d26c 100644 --- a/task_11/src/test.cpp +++ b/task_11/src/test.cpp @@ -1,4 +1,73 @@ - #include -TEST(TopologySort, Simple) { ASSERT_EQ(1, 1); } +#include "substring_search.hpp" + +TEST(Test, Simple) { + std::string S1 = "abbbc"; + std::string P1 = "abc"; + ASSERT_EQ(SubstringSearch(S1, P1), -1); + + std::string S2 = "xyzacbdef"; + std::string P2 = "abc"; + ASSERT_EQ(SubstringSearch(S2, P2), 4); + + std::string S3 = "aabbcc"; + std::string P3 = "abc"; + ASSERT_EQ(SubstringSearch(S3, P3), -1); +} + +TEST(Test, SingleCharacter) { + // Один символ + std::string S1 = "abcdef"; + std::string P1 = "d"; + ASSERT_EQ(SubstringSearch(S1, P1), 4); + + std::string S2 = "abcdef"; + std::string P2 = "z"; + ASSERT_EQ(SubstringSearch(S2, P2), -1); + + std::string S3 = "a"; + std::string P3 = "a"; + ASSERT_EQ(SubstringSearch(S3, P3), 1); +} + +TEST(Test, MultipleOccurrences) { + // Несколько вхождений + std::string S = "abcabcabc"; + std::string P = "cab"; + ASSERT_EQ(SubstringSearch(S, P), 1); +} + +TEST(Test, AllSameLetters) { + // Все буквы одинаковые + std::string S = "aaaaaa"; + std::string P1 = "aaa"; + std::string P2 = "bbb"; + ASSERT_EQ(SubstringSearch(S, P1), 1); + ASSERT_EQ(SubstringSearch(S, P2), -1); +} + +TEST(Test, End) { + // В конце + std::string S = "abcdefgh"; + std::string P = "fgh"; + ASSERT_EQ(SubstringSearch(S, P), 6); +} + +TEST(Test, Start) { + // В начале + std::string S = "jhktruopfd"; + std::string P = "trkjh"; + ASSERT_EQ(SubstringSearch(S, P), 1); +} + +TEST(Test, SubstringGreater) { + // Подстрока больше строки + std::string S1 = "abcd"; + std::string P1 = "skfdksdkf"; + ASSERT_EQ(SubstringSearch(S1, P1), -1); + + std::string S2 = "abcd"; + std::string P2 = "abcde"; + ASSERT_EQ(SubstringSearch(S2, P2), -1); +} 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); +} diff --git a/task_13/src/main.cpp b/task_13/src/main.cpp index 0e4393b..34988c1 100644 --- a/task_13/src/main.cpp +++ b/task_13/src/main.cpp @@ -1,3 +1,21 @@ #include -int main() { return 0; } +#include "scheduling.hpp" + +int main() { + int n; + std::cin >> n; + + std::vector lessons(n); + for (int i = 0; i < n; ++i) { + double start, end; + std::cin >> start >> end; + lessons[i] = {start, end}; + } + + std::vector selected_lessons = GetSelectedLessons(lessons); + std::cout << selected_lessons.size() << "\n"; + + for (Lesson lesson : selected_lessons) + std::cout << lesson.start << " " << lesson.end << "\n"; +} diff --git a/task_13/src/scheduling.hpp b/task_13/src/scheduling.hpp new file mode 100644 index 0000000..cc15478 --- /dev/null +++ b/task_13/src/scheduling.hpp @@ -0,0 +1,30 @@ +#include +#include + +struct Lesson { + double start; + double end; + + // для тестов + bool operator==(const Lesson& other) const { + return start == other.start && end == other.end; + } +}; + +std::vector GetSelectedLessons(std::vector lessons) { + if (lessons.empty()) return lessons; + + sort(lessons.begin(), lessons.end(), + [](const Lesson& a, const Lesson& b) { return a.end < b.end; }); + + std::vector selected_lessons; + + double last_end = -2e9; + for (int i = 0; i < lessons.size(); ++i) { + if (lessons[i].start >= last_end) { + selected_lessons.push_back(lessons[i]); + last_end = lessons[i].end; + } + } + return selected_lessons; +} \ No newline at end of file diff --git a/task_13/src/test.cpp b/task_13/src/test.cpp index 869094d..0ed5760 100644 --- a/task_13/src/test.cpp +++ b/task_13/src/test.cpp @@ -1,4 +1,48 @@ - #include -TEST(TopologySort, Simple) { ASSERT_EQ(1, 1); } +#include "scheduling.hpp" + +TEST(Test, Simple) { + std::vector v1 = {{9, 12}, {10, 13}, {11, 14}}; + std::vector expected1 = {{9, 12}}; + ASSERT_EQ(GetSelectedLessons(v1), expected1); + + // не пересекающиеся + std::vector v2 = {{9, 10}, {10, 11}, {11, 12}}; + std::vector expected2 = {{9, 10}, {10, 11}, {11, 12}}; + ASSERT_EQ(GetSelectedLessons(v2), expected2); + + // пересекающиеся + std::vector v3 = {{9, 12}, {10, 13}, {11, 14}}; + std::vector expected3 = {{9, 12}}; + ASSERT_EQ(GetSelectedLessons(v3), expected3); + + // с вложенными интервалами + std::vector v4 = {{8, 17}, {9, 16}, {10, 15}, {11, 14}, {12, 13}}; + std::vector expected4 = {{12, 13}}; + ASSERT_EQ(GetSelectedLessons(v4), expected4); + + // вещественные числа + std::vector v5 = {{9.1, 9.5}, {9.3, 9.8}, {9.5, 10.2}, {9.8, 10}}; + std::vector expected5 = {{9.1, 9.5}, {9.8, 10}}; + ASSERT_EQ(GetSelectedLessons(v5), expected5); +} + +TEST(Test, Empty) { + std::vector v = {}; + std::vector expected = {}; + ASSERT_EQ(GetSelectedLessons(v), expected); +} + +TEST(Test, SingleLesson) { + std::vector v = {{9, 12}}; + std::vector expected = {{9, 12}}; + ASSERT_EQ(GetSelectedLessons(v), expected); +} + +TEST(Test, SameEnd) { + // Одинаковое время окончания + std::vector v = {{9, 12}, {10, 12}, {11, 12}}; + std::vector expected = {{9, 12}}; + ASSERT_EQ(GetSelectedLessons(v), expected); +} diff --git a/task_14/src/main.cpp b/task_14/src/main.cpp index c3aeba4..e8e7c50 100644 --- a/task_14/src/main.cpp +++ b/task_14/src/main.cpp @@ -1 +1,22 @@ -int main() { return 0; } \ No newline at end of file +#include + +#include "non_decreasing_ranges.hpp" + +int main() { + int n, m, k; + std::cin >> n >> m >> k; + + std::vector> table(n, std::vector(m)); + for (int i = 0; i < n; ++i) + for (int j = 0; j < m; ++j) std::cin >> table[i][j]; + + std::vector max_right_rows(n); + max_right_rows = GetNonDecreasingRanges(table); + + for (int i = 0; i < k; ++i) { + int left, right; + std::cin >> left >> right; + std::cout << IsThereNonDecreasingColumn(left, right, max_right_rows) + << "\n"; + } +} \ No newline at end of file diff --git a/task_14/src/non_decreasing_ranges.hpp b/task_14/src/non_decreasing_ranges.hpp new file mode 100644 index 0000000..3839d4f --- /dev/null +++ b/task_14/src/non_decreasing_ranges.hpp @@ -0,0 +1,40 @@ +#include +#include + +std::vector GetNonDecreasingRanges( + const std::vector>& table) { + if (table.empty()) return std::vector{}; + int n = table.size(); + int m = table[0].size(); + + std::vector> max_right_by_columns( + n, std::vector(m, 0)); // максимальное значение + // правой строки для каждого столбца + for (int j = 0; j < m; ++j) max_right_by_columns[n - 1][j] = n - 1; + + std::vector max_right_rows( + n, 0); // i-ый элемент - максимальное значение + // правой строки из всех столбцов для i-ой строки + + for (int i = n - 2; i >= 0; --i) { + int max_in_row = i; + for (int j = 0; j < m; ++j) { + if (table[i][j] <= table[i + 1][j]) + max_right_by_columns[i][j] = max_right_by_columns[i + 1][j]; + else + max_right_by_columns[i][j] = i; + max_in_row = std::max(max_in_row, max_right_by_columns[i][j]); + } + max_right_rows[i] = max_in_row; + } + return max_right_rows; +} + +std::string IsThereNonDecreasingColumn(int left, int right, + const std::vector& max_right_rows) { + if (max_right_rows.empty()) return "No"; + if (max_right_rows[left - 1] >= right - 1) + return "Yes"; + else + return "No"; +} \ No newline at end of file diff --git a/task_14/src/test.cpp b/task_14/src/test.cpp index a42caa4..b53950a 100644 --- a/task_14/src/test.cpp +++ b/task_14/src/test.cpp @@ -1,23 +1,92 @@ #include -#include - -TEST(CanReachNonDecreasingSegment, 1) { - // ASSERT_EQ(SolveFunction(5, 4, 6, - // std::vector>{{1, 2, 3, 5}, - // {3, 1, 3, 2}, - // {4, 5, 2, 3}, - // {5, 5, 3, 2}, - // {4, 4, 3, 4}}, - // std::vector>{ - // {1, 1}, {2, 5}, {4, 5}, {3, 5}, {1, 3}, {1, - // 5}}), - // (std::vector{"Yes", "No", "Yes", "Yes", "Yes", - // "No"})); +#include "non_decreasing_ranges.hpp" + +TEST(CanReachNonDecreasingSegment, Simple) { + std::vector answers = {"Yes", "No", "Yes", "Yes", "Yes", "No"}; + std::vector> ranges = {{1, 1}, {2, 5}, {4, 5}, + {3, 5}, {1, 3}, {1, 5}}; + std::vector> table = { + {1, 2, 3, 5}, {3, 1, 3, 2}, {4, 5, 2, 3}, {5, 5, 3, 2}, {4, 4, 3, 4}}; + + std::vector max_right_rows = GetNonDecreasingRanges(table); + for (int i = 0; i < answers.size(); ++i) { + ASSERT_EQ(IsThereNonDecreasingColumn(ranges[i].first, ranges[i].second, + max_right_rows), + answers[i]); + } +} + +TEST(CanReachNonDecreasingSegment, OneRow) { + std::vector answers = {"Yes"}; + std::vector> ranges = {{1, 1}}; + std::vector> table = {{1, 1}}; + + std::vector max_right_rows = GetNonDecreasingRanges(table); + for (int i = 0; i < answers.size(); ++i) { + ASSERT_EQ(IsThereNonDecreasingColumn(ranges[i].first, ranges[i].second, + max_right_rows), + answers[i]); + } +} + +TEST(CanReachNonDecreasingSegment, EmptyTable) { + std::vector answers = {"No", "No"}; + std::vector> ranges = {{52, 67}, {4, 2}}; + std::vector> table = {{}}; + + std::vector max_right_rows = GetNonDecreasingRanges(table); + for (int i = 0; i < answers.size(); ++i) { + ASSERT_EQ(IsThereNonDecreasingColumn(ranges[i].first, ranges[i].second, + max_right_rows), + answers[i]); + } } -TEST(CanReachNonDecreasingSegment, 2) { - // ASSERT_EQ(SolveFunction(1, 1, 1, std::vector>{{1, 1}}, - // std::vector>{{1, 1}}), - // (std::vector{"Yes"})); +TEST(CanReachNonDecreasingSegment, NegativeNumbers) { + std::vector answers = {"Yes", "No", "Yes", "No", "Yes", "Yes"}; + std::vector> ranges = {{1, 1}, {2, 4}, {3, 4}, + {1, 4}, {1, 3}, {1, 2}}; + std::vector> table = { + {1, 2, 3, 0}, + {-3, 6, 3, 2}, + {4, 5, 52, 3}, + {0, 5, 3, 2}, + }; + + std::vector max_right_rows = GetNonDecreasingRanges(table); + for (int i = 0; i < answers.size(); ++i) { + ASSERT_EQ(IsThereNonDecreasingColumn(ranges[i].first, ranges[i].second, + max_right_rows), + answers[i]); + } +} + +TEST(CanReachNonDecreasingSegment, AllSame) { + std::vector answers = {"Yes", "Yes", "Yes", "Yes", "Yes", "Yes"}; + std::vector> ranges = {{1, 1}, {2, 5}, {4, 5}, + {3, 5}, {1, 3}, {1, 5}}; + std::vector> table = { + {5, 5, 5, 5}, {5, 5, 5, 5}, {5, 5, 5, 5}, {5, 5, 5, 5}, {5, 5, 5, 5}}; + + std::vector max_right_rows = GetNonDecreasingRanges(table); + for (int i = 0; i < answers.size(); ++i) { + ASSERT_EQ(IsThereNonDecreasingColumn(ranges[i].first, ranges[i].second, + max_right_rows), + answers[i]); + } +} + +TEST(CanReachNonDecreasingSegment, OneColumn) { + std::vector answers = {"Yes", "Yes", "No", "No", "No", "No"}; + std::vector> ranges = {{1, 1}, {2, 3}, {4, 5}, + {3, 5}, {1, 3}, {1, 5}}; + std::vector> table = {{5}, {2}, {4}, {4}, {0}}; + + std::vector max_right_rows = GetNonDecreasingRanges(table); + for (int i = 0; i < answers.size(); ++i) { + ASSERT_EQ(IsThereNonDecreasingColumn(ranges[i].first, ranges[i].second, + max_right_rows), + answers[i]); + } }