Информатика

15 724 задачивместе с подтемами
Число у задачи — рейтинг сложности, слово рядом — насколько она трудна по сравнению с другими задачами такого же типа. Шкалы задач с ответом и задач с кодом между собой не сравниваются. Рядом — счётчики попыток: успешные, неуспешные.

В деревьях решений для работы с непрерывными признаками нужно найти  оптимальный порог разделения.

Порог — это число, которое делит данные  на две части: значения ≤ порога идут влево, значения > порога — вправо.

 

Пример:

Значения:  [1, 3, 5, 7, 9]
Метки:     [0, 0, 1, 1, 1]

Если выбрать порог = 4:
- Левая часть (≤ 4): значения [1, 3], метки [0, 0]
- Правая часть (> 4): значения [5, 7, 9], метки [1, 1, 1]

Это хорошее разделение! Левая часть чистая, правая чистая.


Алгоритм поиска лучшего порога:

1. Отсортируй уникальные значения признака
2. Для каждой пары соседних уникальных значений:
   - Порог = среднее этих двух значений
   - Раздели данные по порогу
   - Посчитай информационную выгоду
3. Верни порог с максимальной выгодой

Реализуйте алгоритм поиска лучшего порога.


Формат входных данных
- Первая строка: N — количество элементов
- Вторая строка: N вещественных чисел — значения признака
- Третья строка: N целых чисел (0 или 1) — метки классов

Формат выходных данных
- Первая строка: оптимальный порог (вещественное число, 4 знака после запятой)
- Вторая строка: информационная выгода (вещественное число, 4 знака после запятой)

Теперь соберём все части вместе и создадим полноценное дерево решений!

Дерево решений — это алгоритм машинного обучения, который:
1. Находит лучший признак для разделения данных (по информационной выгоде)
2. Рекурсивно строит поддеревья для каждой части
3. Останавливается, когда данные "чистые" или достигнута максимальная глубина

Пример работы на данных OR (логическое ИЛИ):
X = [[0,0], [0,1], [1,0], [1,1]]
y = [0, 1, 1, 1]

Дерево может выглядеть так:
            [feature 0]
             /       \
        x[0]=0      x[0]=1
           /           \
      [feature 1]    лист(1)
       /      \
   лист(0)  лист(1)

Задача

Используйте класс TreeNode, реализованный в предыдущем задании.
Реализуйте класс DecisionTree с методами:

0.  __init__(self, max_depth=10)`
   Инициализирует дерево решений.
   
   Параметры:
   - max_depth: максимальная глубина дерева (по умолчанию 10)
   Что нужно сделать:
   - Сохранить max_depth как атрибут объекта
   - Создать атрибут self.root и установить его в None (корень дерева будет создан позже при вызове fit)

1. entropy(self, labels)
   Считает энтропию списка меток.
   H = -p₀·log₂(p₀) - p₁·log₂(p₁)
   Если список пустой, возвращает 0.
   Если p=0, соответствующее слагаемое = 0.

2. find_best_split(self, X, y)
   Находит лучший признак для разделения.
   - Для каждого признака считает информационную выгоду
   - Возвращает кортеж: (индекс_лучшего_признака, информационная_выгода)
   - Если все признаки дают нулевую выгоду, возвращает (0, 0)

3. build_tree(self, X, y, depth=0)
   Рекурсивно строит дерево. Возвращает TreeNode.
   
   Условия остановки (создать лист):
   - Все метки одинаковые → лист с этой меткой
   - Достигнута max_depth → лист с самым частым классом
   - Нет признаков (X пустой или X[0] пустой) → лист с самым частым классом
   - Лучшее разделение даёт нулевую выгоду → лист с самым частым классом
   
   Иначе:
   - Найти лучший признак
   - Разделить данные: левая часть где x[feature]=0, правая где x[feature]=1
   - Рекурсивно построить поддеревья
   - Вернуть TreeNode с feature_index и поддеревьями

4. fit(self, X, y) - берёт данные (примеры X и ответы y) и строит из них дерево решений, которое потом будет делать предсказания.

5. predict(self, X) - берёт новые данные и для каждого примера спрашивает у дерева: "Какой ответ?"
 

Класс TreeNode уже реализован в предыдущем задании. Скопируйте его здесь.
Примеры
Пример 1
X = [[0,0], [0,1], [1,0], [1,1]]
y = [0, 1, 1, 1]
tree = DecisionTree(max_depth=3)
tree.fit(X, y)
tree.predict(X)  # [0, 1, 1, 1]
Пример 2
X = [[0,0], [0,1], [1,0], [1,1]]
y = [0, 0, 0, 1]
tree = DecisionTree(max_depth=3)
tree.fit(X, y)
tree.predict(X)  # [0, 0, 0, 1]
Пример 3
X = [[0,0], [0,1], [1,0], [1,1]]
y = [1, 1, 1, 0]
tree = DecisionTree(max_depth=3)
tree.fit(X, y)
tree.predict(X)  # [1, 1, 1, 0]
 Дерево решений состоит из узлов двух типов:

1. Внутренний узел — содержит номер признака (feature_index) для разделения.
   Если значение признака = 0, идём в левое поддерево.
   Если значение признака = 1, идём в правое поддерево.

2. Лист — содержит предсказание (prediction), которое возвращается как ответ.
Пример дерева:
                    [feature_index 0]
                     /       \
                значение=0   значение=1
                   /           \
              [feature_index 1]    лист(1)
               /      \
           лист(0)  лист(1)
Для примера [0, 1, 0]:
- Корень: feature_index=0, значение признака 0 равно 0 → идём налево
- Узел: feature_index=1, значение признака 1 равно 1 → идём направо
- Лист: prediction=1 → ответ 1

Реализуй класс TreeNode с тремя методами:

1. __init__(self, feature_index=None, left=None, right=None, prediction=None)
   Сохраняет все параметры как атрибуты объекта.

2. is_leaf(self)
   Возвращает True, если узел является листом (у него есть prediction).
   Возвращает False, если узел внутренний.

3. predict_one(self, sample)
   Делает предсказание для одного примера.
   - Если узел — лист, возвращает prediction
   - Иначе смотрит на sample[feature_index]:
     - если 0 → рекурсивно вызывает predict_one у левого поддерева
     - если 1 → рекурсивно вызывает predict_one у правого поддерева

 
 

Примеры использования:

Пример 1
# Создание листа
leaf = TreeNode(prediction=1)
leaf.is_leaf()              # True
leaf.predict_one([0, 1, 0]) # 1

Пример 2
# Создание дерева глубины 1
tree = TreeNode(
    feature_index=0,
    left=TreeNode(prediction=0),
    right=TreeNode(prediction=1)
)
tree.is_leaf()              # False
tree.predict_one([0, 1, 0]) # 0 (sample[0]=0 → налево)
tree.predict_one([1, 0, 0]) # 1 (sample[0]=1 → направо)
Дан список меток (0 и 1) до разделения и два списка после разделения 
на левую и правую части. Вычисли информационную выгоду.

Формат входных данных
- Первая строка: N — количество элементов до разделения
- Вторая строка: N чисел (0 или 1) — метки до разделения
- Третья строка: L — количество элементов в левой части
- Четвёртая строка: L чисел (0 или 1) — метки левой части
- Пятая строка: R — количество элементов в правой части
- Шестая строка: R чисел (0 или 1) — метки правой части

Гарантируется, что L + R = N и L, R > 0.

Формат выходных данных
Одно число — информационная выгода, округлённое до 4 знаков после запятой.

На крыше дома в Простоквашино висит N сосулек. Каждую минуту все сосульки одновременно капают: каждая сосулька уменьшается на 1 сантиметр. Когда длина сосульки становится 0 или меньше, она падает и исчезает.

Дядя Фёдор хочет узнать, через сколько минут упадёт последняя сосулька.

Входные данные: В первой строке число N (1 ≤ N ≤ 1000). Во второй строке N целых чисел от 1 до 10000 — начальные длины сосулек.

Выходные данные: Через сколько минут упадёт последняя сосулька.

Матроскин украшает окно к Новому году. Окно представляет собой сетку N×M клеток. Он хочет нарисовать рамку по периметру окна (все крайние клетки) специальной краской. Сколько клеток нужно закрасить?

Входные данные: Два целых числа N и M (1 ≤ N, M ≤ 1000) — размеры окна. Каждое число записано в отдельной строке.

Выходные данные: Количество клеток в рамке.

В Простоквашино построили ледяную горку. Она состоит из N ступенек. На каждой ступеньке написано число — сколько секунд нужно отдохнуть, если встать на неё. Дядя Фёдор стартует перед первой ступенькой и может прыгать на 1 или 2 ступеньки вперёд. Ему нужно добраться до вершины (встать на последнюю ступеньку), потратив минимум времени на отдых.

Входные данные: В первой строке число N (1 ≤ N ≤ 10). Во второй строке N целых чисел от 0 до 100 — время отдыха на каждой ступеньке.

Выходные данные: Минимальное суммарное время отдыха.

Под ёлкой лежит N подарков в ряд. Известна радость, которую принесёт каждый подарок. По традиции Простоквашино, нельзя брать два соседних подарка — это невежливо. Дядя Фёдор хочет выбрать подарки так, чтобы суммарная радость была максимальной.

Входные данные: В первой строке число N (1 ≤ N ≤ 10). Во второй строке N целых чисел от 1 до 1000 — радость от каждого подарка.

Выходные данные: Максимальная суммарная радость.

Дети Простоквашино выстроили N санок в ряд. Каждые санки имеют определённый вес. Дядя Фёдор хочет выбрать несколько санок подряд (непрерывный отрезок), чтобы их суммарный вес был как можно ближе к числу S (грузоподъёмность трактора), но не превышал его.

Найдите максимальный суммарный вес санок, который можно погрузить на трактор.

Входные данные: В первой строке два числа N и S (1 ≤ N ≤ 10, 1 ≤ S ≤ 10^6). Во второй строке N целых чисел от 1 до 10 — веса санок.

Выходные данные: Максимальный суммарный вес санок, не превышающий S. Если ни одни санки не помещаются, выведите 0.

Почтальон Печкин принёс в Простоквашино ёлку высотой H сантиметров. Каждый день ёлка осыпается и становится ниже на D сантиметров, но не может стать ниже нуля. Новый год наступит через N дней.

Какой высоты будет ёлка в новогоднюю ночь (после N дней осыпания)?

Входные данные: Три целых числа H, D, N (1 ≤ H ≤ 1000, 1 ≤ D ≤ 100, 1 ≤ N ≤ 100). Каждое число записано в отдельной строке.

Выходные данные: Высота ёлки в новогоднюю ночь.

Галчонок выучил N не обязательно разных слов и говорит их по очереди, повторяя циклически. Матроскин хочет узнать, сколько раз за день Галчонок скажет слово «kto-tam», если всего за день он произносит K слов.

Входные данные: В первой строке число N, во второй число K (1 ≤ N ≤ 100, 1 ≤ K ≤ 109) — количество слов, которые повторяет Галчонок и общее количество произнесённых слов. В следующих N строках записаны слова Галчонка в том порядке, как он их повторяет (строки состоят из маленьких латинских букв и дефисов, длиной до 20 символов).

Выходные данные: Сколько раз Галчонок скажет «kto-tam».

Утром Дядя Фёдор вышел на улицу и увидел цепочку следов на снегу. Он записал глубину каждого следа в сантиметрах. Дядя Фёдор хочет найти самый глубокий след, чтобы понять, кто из жителей деревни проходил мимо (чем тяжелее, тем глубже след).

Входные данные: В первой строке число N (1 ≤ N ≤ 1000) — количество следов. Во второй строке N целых чисел от 1 до 100 — глубина каждого следа.

Выходные данные: Два числа через пробел: максимальная глубина и номер следа с такой глубиной (если таких несколько, выведите номер первого). Следы нумеруются с единицы.

Шарик украшает ёлку гирляндой из N лампочек. Лампочки мигают по очереди: первая загорается в момент времени 0, вторая — в момент 1, третья — в момент 2, и так далее. Когда загорается последняя лампочка, следующей снова загорается первая, потом вторая и т.д.

Шарик хочет узнать, какая по счёту лампочка будет гореть в момент времени T.

Входные данные: Два целых числа N и T (1 ≤ N ≤ 1000, 0 ≤ T ≤ 109) — количество лампочек и момент времени.

Выходные данные: Номер лампочки, которая горит в момент T.

✓ 519✗ 900400лёгкаяВойти и решать

Матроскин готовит бутерброды для новогоднего стола. У него есть N кусков хлеба и M кусков колбасы. На каждый бутерброд нужен один кусок хлеба и два куска колбасы. Сколько бутербродов сможет приготовить Матроскин?

Входные данные: Два целых числа N и M (0 ≤ N, M ≤ 1000) — количество кусков хлеба и колбасы.  Каждое число записано в отдельной строке.

Выходные данные: Одно число — максимальное количество бутербродов.

Печка в Простоквашино работает интересно: каждый час она повышает температуру в доме на A градусов, но из-за щелей в стенах за тот же час уходит B градусов тепла. Сейчас в доме T градусов.

Матроскин считает, что комфортная температура — не меньше C градусов. Определите, будет ли в доме когда-нибудь комфортно, и если да — через сколько полных часов.

Входные данные: Четыре целых числа T, A, B, C (−50 ≤ T ≤ 50, 1 ≤ A ≤ 10, 1 ≤ B ≤ 10, 1 ≤ C ≤ 50) — начальная температура, прирост от печки, потери тепла и желаемая температура. Каждое число вводится в отдельной строке.

Выходные данные: Число часов до достижения комфортной температуры, или «Никогда», если температура не достигнет нужной.

Кот Матроскин заготавливает дрова на зиму. Печка Галчонка потребляет ровно K поленьев в день. Матроскин заготовил N поленьев и хочет узнать, на сколько полных дней хватит дров.

Входные данные: Вводятся два целых числа N и K (1 ≤ N ≤ 10000, 1 ≤ K ≤ 100) — количество заготовленных поленьев и дневной расход. Каждое число записано в отдельной строке.

Выходные данные: Одно число — количество полных дней, на которые хватит дров.

Дядя Фёдор решил написать письмо Деду Морозу. Он знает, что письмо дойдёт быстрее, если в нём чётное количество слов — так устроена волшебная почта. Шарик подсказал, что если слов нечётное, можно дописать в конце слово «Пожалуйста».

Дядя Фёдор написал письмо и хочет понять: нужно ли дописывать слово или письмо уже готово к отправке?

Входные данные: В первой строке одно целое число N (1 ≤ N ≤ 100) — количество слов в письме.

Выходные данные: Выведите «Готово», если письмо можно отправлять, или «Дописать», если нужно добавить слово.

Разбирая старые задачи олимпиады, Петя наткнулся на алгоритм рекурсивного закрашивания растрового изображения. У Пети есть черно-белое (bitmap) изображение размером 13 на 13 пикселей. На изображении присутствует замкнутый контур, как приведено на рисунке. Пиксели внутри контура пронумерованы.


Традиционно для компьютерной графики, система координат имеет начало в верхнем левому углу, ось X направлена слева направо, а ось Y – сверху вниз.
Алгоритм рекурсивного закрашивания заключается в рекурсивном вызове процедуры «Закрасить», которой передаются два параметра – координаты X и Y пикселя.
Процедура Закрасить(X, Y), может быть описана следующим образом:
1. Если цвет пикселя с координатами (X, Y) белый, то:
a. Изменить цвет пикселя с этими координатами на черный;
b. Вызвать процедуру Закрасить(X+1, Y);
c. Вызвать процедуру Закрасить(X, Y+1);
d. Вызвать процедуру Закрасить(X-1, Y);
e. Вызвать процедуру Закрасить(X, Y-1);
2.Иначе завершить процедуру.
Известно, что последний закрашенный пиксель, перед завершением процедуры, имел номер 29. Сколько существует пикселей внутри контура, в которых можно исходно вызвать процедуру «Закрасить» так, чтобы получить такой результат?

В ответе укажите целое число.

Нарисуйте цветной рисунок из трёх дуг (каждая дуга это полуокружность - угол 180 градусов)

  1. Начало в (0, 0).
  2. Фиолетовая дуга радиусом 150 (рисуется вверх вправо).
  3. Желтая дуга радиусом 100.
  4. Зеленая дуга радиусом 50.
  5. Жёлтая и зеленая дуги находятся внутри фиолетовой так как показано на рисунке

У каждой дуги цвет контура и цвет заливки одинаковый

Поделиться
Класснуть