ИУП: интенсив 7 дней + диагностический пакет (32 вопроса, 9 задач с автопроверкой)
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
// Задача 05 — длина НВП за O(n log n). Заполни реализацию.
|
||||
#include <vector>
|
||||
|
||||
int lis_length(const std::vector<int>& a) {
|
||||
(void)a;
|
||||
return 0; // TODO
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
# Задача 05 — длиннейшая возрастающая подпоследовательность (C++)
|
||||
|
||||
```c++
|
||||
int lis_length(const std::vector<int>& a); // длина НВП (строго возрастающей)
|
||||
```
|
||||
|
||||
Требования:
|
||||
- пустая последовательность → 0;
|
||||
- работа за O(n log n); наивное O(n²) не пройдёт проверку на 100 000 элементах
|
||||
(внутренний тест меряет время и роняет прогон при > 2 с);
|
||||
- подпоследовательность не обязана быть непрерывной.
|
||||
|
||||
Проверка: `python3 grade.py 05`. Критерий: все `ok`, сборка без предупреждений.
|
||||
Разбор после сдачи: «хвосты» — массив минимальных последних элементов + lower_bound.
|
||||
@@ -0,0 +1,47 @@
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <random>
|
||||
#include <chrono>
|
||||
#include <algorithm>
|
||||
#include "solution.cpp"
|
||||
|
||||
static int failures = 0;
|
||||
#define CHECK(cond, name) do { if (cond) std::printf("ok %s\n", name); \
|
||||
else { std::printf("FAIL %s (line %d)\n", name, __LINE__); ++failures; } } while (0)
|
||||
|
||||
int main() {
|
||||
CHECK(lis_length({}) == 0, "пустая -> 0");
|
||||
CHECK(lis_length({5}) == 1, "один элемент -> 1");
|
||||
CHECK(lis_length({1, 2, 3}) == 3, "возрастающая -> вся длина");
|
||||
CHECK(lis_length({3, 2, 1}) == 1, "убывающая -> 1");
|
||||
CHECK(lis_length({10, 9, 2, 5, 3, 7, 101, 18}) == 4, "классика -> 4");
|
||||
CHECK(lis_length({7, 7, 7}) == 1, "равные элементы -> строго возрастающая длина 1");
|
||||
CHECK(lis_length({0, 1, 0, 3, 2, 3}) == 4, "лекод-пример -> 4");
|
||||
CHECK(lis_length({2, 2, 2, 3}) == 2, "дубли + рост -> 2");
|
||||
CHECK(lis_length({-5, -4, -3, -2}) == 4, "отрицательные -> 4");
|
||||
|
||||
// производительность: худший случай для наивного DP
|
||||
{
|
||||
std::vector<int> big(100000);
|
||||
for (int i = 0; i < 100000; ++i) big[i] = i;
|
||||
auto t0 = std::chrono::steady_clock::now();
|
||||
int r = lis_length(big);
|
||||
double sec = std::chrono::duration<double>(std::chrono::steady_clock::now() - t0).count();
|
||||
std::printf(" (100k возрастающих: result=%d, time=%.3fs)\n", r, sec);
|
||||
CHECK(r == 100000, "100k возрастающих -> 100000");
|
||||
CHECK(sec < 2.0, "100k за < 2 c (требуется O(n log n))");
|
||||
}
|
||||
{
|
||||
std::mt19937 rng(12345);
|
||||
std::vector<int> big(100000);
|
||||
for (auto& x : big) x = int(rng() % 100000);
|
||||
auto t0 = std::chrono::steady_clock::now();
|
||||
int r = lis_length(big);
|
||||
double sec = std::chrono::duration<double>(std::chrono::steady_clock::now() - t0).count();
|
||||
std::printf(" (100k случайных: result=%d, time=%.3fs)\n", r, sec);
|
||||
CHECK(r > 300 && r < 800, "100k случайных: результат в разумном диапазоне");
|
||||
CHECK(sec < 2.0, "100k случайных за < 2 c");
|
||||
}
|
||||
std::printf(failures ? "\nFAILURES: %d\n" : "\nALL PASS\n", failures);
|
||||
return failures ? 1 : 0;
|
||||
}
|
||||
Reference in New Issue
Block a user