search icon search icon ВЕРСИЯ ДЛЯ СЛАБОВИДЯЩИХ

Предметный тур. Информатика. 3 этап

Информатика. 8–11 классы
Задача 1.1.(15 баллов)
Високосный год

Имя входного файла: стандартный ввод или input.txt.

Имя выходного файла: стандартный вывод или output.txt.

Ограничение по времени выполнения программы: 1 с.

Ограничение по памяти: 256 Мбайт.

Условие

Как известно, количество дней в году, согласно Григорианскому календарю, определяется следующим образом:

  • если номер года не делится на \(4\), то количество дней в году равно \(365\);
  • если номер года делится на \(4\), но не делится на \(100\), то количество дней в году равно \(366\);
  • если номер года делится на \(100\), но не делится на \(400\), то количество дней в году равно \(365\);
  • если номер года делится на \(400\), то количество дней в году равно \(366\).

Требуется по номеру года определить, сколько в нем минут согласно Григорианскому календарю.

Формат входных данных

Первая строка содержит единственное целое число \(y\) (\(1\,583 \leqslant y \leqslant 2\,025\)) — номер года.

Формат выходных данных

Выведите одно целое число — количество минут в \(y\) году.

Тестовые данные

Номер тестаСтандартный вводСтандартный вывод
1
2025
525600

Решение

Используем условный оператор для реализации логики, описанной в условии задачи. Чтобы определить, делится ли \(x\) на \(y\), можно проверить, выполняется ли условие \(x \% y == 0\). Здесь \(x \% y\) обозначает остаток от деления \(x\) на \(y\), где \(\%\) — оператор, который находит остаток.

Если \(x\) делится на \(y\), то остаток от деления \(x\) на \(y\) равен \(0\), поэтому приведенный выше код определяет делимость.

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

Пример программы-решения

Ниже представлено решение на языке Python.

Python
y = int(input())
if y % 4:
    print(365 * 60 * 24)
else:
    if y % 100:
        print(366 * 60 * 24)
    else:
        if y % 400:
            print(365 * 60 * 24)
        else:
            print(366 * 60 * 24)

Задача 1.2.(18 баллов)
Очень сложная математика

Имя входного файла: стандартный ввод или input.txt.

Имя выходного файла: стандартный вывод или output.txt.

Ограничение по времени выполнения программы: 1 с.

Ограничение по памяти: 256 Мбайт.

Условие

В задаче требуется по данным целым числам \(a\), \(b\) и \(c\) определить значение следующего выражения: \(\sum\limits_{i=1}^{a} \sum\limits_{j=1}^{b} \sum\limits_{k=1}^{c} i \cdot j \cdot k\).

Иными словами, необходимо вычислить сумму произведений \(i \cdot j \cdot k\) по всем тройкам целых чисел \((i, j, k)\) таких, что \(1 \leqslant i \leqslant a\), \(1 \leqslant j \leqslant b\) и \(1 \leqslant k \leqslant c\).

Формат входных данных

Единственная строка содержит три целых числа \(a\), \(b\) и \(c\) (\(1 \leqslant a, b, c \leqslant 10^9\)).

Формат выходных данных

Выведите одно целое число — значение искомой суммы. Так как ответ может быть достаточно большим, выведите остаток от деления суммы на число \(998244353\).

Тестовые данные

Номер тестаСтандартный вводСтандартный вывод
1
1 2 3
18
2
1000000000 987654321 123456789
951633476

Примечания

В первом примере искомая сумма вычисляется следующим образом: \[(1 \cdot 1 \cdot 1)+(1 \cdot 1 \cdot 2)+(1 \cdot 1 \cdot 3)+(1 \cdot 2 \cdot 1)+(1 \cdot 2 \cdot 2)+(1 \cdot 2 \cdot 3)=1+2+3+2+4+6=18.\]

Ответ во втором примере очень большой. Убедитесь в том, что остаток от деления ответа на число \(998244353\) был взят правильно.

Решение

Имеем:

\[\sum\limits_{i=1}^{a} \sum\limits_{j=1}^{b} \sum\limits_{k=1}^{c} i \cdot j \cdot k = \sum\limits_{i=1}^{a} i \cdot \sum\limits_{j=1}^{b} j \cdot \sum\limits_{k=1}^{c} k = \frac{a(a+1)}{2} \cdot \frac{b(b+1)}{2} \cdot \frac{c(c+1)}{2}.\]

Пример программы-решения

Ниже представлено решение на языке Python.

Python
a, b, c = map(int, input().split())
sum = a * (a + 1) // 2 * b * (b + 1) // 2 * c * (c + 1) // 2
print(sum % 998244353)
Задача 1.3.(20 баллов)
Угощение

Имя входного файла: стандартный ввод или input.txt.

Имя выходного файла: стандартный вывод или output.txt.

Ограничение по времени выполнения программы: 1 с.

Ограничение по памяти: 256 Мбайт.

Условие

На планете Метароботов праздник.

Роботы готовят очень большие угощения к празднику. Угощение \(R\)-ранга (\(R\) — натуральное число или 0):

  • Угощение \(0\)-ранга — это одна «Чистая энергия».
  • Угощение \(R\)-ранга, где \(R > 0\), — представляет собой железяку, угощение \((R-1)\)-ранга, «Чистую энергию», угощение \((R-1)\)-ранга и железяку, сложенные друг на друга.

Например, угощение \(1\)-ранга и угощение \(2\)-ранга выглядят следующим образом: MEEEM и ММEEEМEМEEEММ, где M — железяка, а E — «Чистая энергия».

На праздник приготовили угощение \(N\)-ранга. Один хитрый робот съел \(X\) элементов сверху. Сколько «Чистой энергии» съел робот?

Формат входных данных

Даны два числа \(N\) и \(X\), \(1 \leqslant N \leqslant 50\), \(1 \leqslant X \leqslant\) (максимальное число слоев в угощении \(N\)-ранга).

Формат выходных данных

Выведите количество съеденной «Чистой энергии».

Тестовые данные

Номер тестаСтандартный вводСтандартный вывод
1
2 7
4
2
1 1
0
3
50 4321098765432109
2160549382716056

Решение

Пусть:

  • \(a_i\) — общее количество элементов (толщина) угощения ранга \(i\) (\(i \geqslant 0\)),
  • \(p_i\) — количество элементов «Чистая энергия» (E) в угощении ранга \(i\) (\(i \geqslant 0\)).

Эти величины вычисляются рекуррентно: \[\begin{cases} a_0 = 1 & \text{(только E)}, \\ a_i = 2a_{i-1} + 3 & \text{при } i \geqslant 1, \end{cases} \quad \begin{cases} p_0 = 1 & \text{(только E)}, \\ p_i = 2p_{i-1} + 1 & \text{при } i \geqslant 1. \end{cases}\]

Искомое количество элементов «Чистая энергия» в верхних \(X\) слоях угощения ранга \(N\) обозначим как \(f(N, X)\).

Угощение ранга 0 — это просто E: \[f(0, X) = \begin{cases} 1 & \text{при } X \geqslant 1, \\ 0 & \text{при } X = 0. \end{cases}\]

Угощение ранга \(N\) имеет структуру: \[\text{M} + \text{Угощение}_{N-1} + \text{E} + \text{Угощение}_{N-1} + \text{M}.\]

Разберем возможные значения \(X\):

  1. \(X = 1: f(N, 1) = 0\) (верхний слой — M).
  2. \(1 < X \leqslant 1 + a_{N-1}: f(N, X) = f(N-1, X - 1)\).
  3. \(X = 2 + a_{N-1}: f(N, X) = p_{N-1} + 1\).
  4. \(2 + a_{N-1} < X \leqslant 2 + 2a_{N-1}: f(N, X) = p_{N-1} + 1 + f(N-1, X - (2 + a_{N-1}))\).
  5. \(X \geqslant 3 + 2a_{N-1}: f(N, X) = 2p_{N-1} + 1\).

Если реализовать это как рекурсивную функцию, то ответ может быть найден за \(N + 1\) шагов вычислений.

Пример программы-решения

Ниже представлено решение на языке Python.

Python
N, X = map(int, input().split())
a, p = [1], [1]
for i in range(N):
    a.append(a[i] * 2 + 3)
    p.append(p[i] * 2 + 1)
def f(N, X):
    if N == 0:
        return 0 if X <= 0 else 1
    elif X <= 1 + a[N-1]:
        return f(N-1, X-1)
    else:
        return p[N-1] + 1 + f(N-1, X-2-a[N-1])

print(f(N, X))
Задача 1.4.(22 балла)
Сумма цифр

Имя входного файла: стандартный ввод или input.txt.

Имя выходного файла: стандартный вывод или output.txt.

Ограничение по времени выполнения программы: 1 с.

Ограничение по памяти: 256 Мбайт.

Условие

Для целых чисел \(b\) \((b \geqslant 2)\) и \(n\) \((n \geqslant 1)\) определим функцию \(f(b, n)\) следующим образом:

  • \(f(b, n) = n\), где \(n < b\);
  • \(f(b, n) = f(b,\,{\rm floor}(\frac nb)) + (n \ {\rm mod} \ b)\), где \(n \geqslant b\).

\({\rm floor}(n / b)\) — наибольшее целое число, не превосходящее \(n / b\), а (\(n \ {\rm mod} \ b\)) — остаток от деления числа \(n\) на число \(b\).

Менее формально \(f(b, n)\) равно сумме цифр числа \(n\), записанного в системе счисления с основанием \(b\).

Например:

  • \(f(10,\,87654)=8+7+6+5+4=30\);
  • \(f(100,\,87654)=8+76+54=138\).

Даны два числа \(n\) и \(s\). Требуется определить, существует ли целое число \(b\) \((b \geqslant 2)\) такое, что \(f(b, n)=s\). Если ответ существует, то найдите наименьшее такое \(b\).

Формат входных данных

Даны два числа \(n\) \((1 \leqslant n \leqslant 10^{11})\) и \(s\) \((1 \leqslant s \leqslant 10^{11})\).

Формат выходных данных

Если существует целое число \(b\) \((b \geqslant 2)\) такое, что \(f(b, n) = s\), выведите наименьшее такое \(b\). Если такого числа не существует, то выведите (\(-1\)).

Тестовые данные

Номер тестаСтандартный вводСтандартный вывод
1
87654
30
10
2
87654
138
100

Решение

Очевидно, что в случае \(s = n\) ответом будет \(n + 1\).

В остальных случаях сначала проводится полный перебор для нахождения целого числа \(b\) в диапазоне \(2 \leqslant b \leqslant \sqrt{n}\), удовлетворяющего условию \(f(b, n) = s\). Если такое \(b\) существует, то минимальное из них будет ответом.

Если такого \(b\) не найдено, то необходимо проверить наличие целого числа \(b\) в диапазоне \(\sqrt{n} < b \leqslant n\), удовлетворяющего условию \(f(b, n) = s\). Заметим, что при \(b > \sqrt{n}\) число \(n\) в системе счисления с основанием \(b\) будет двузначным. Пусть старшая цифра будет \(p\), а младшая — \(q\) (где \(1 \leqslant q < b\), \(0 \leqslant q < b\)), тогда \[\label{eq:inf_bd_01} n = p \cdot b + q.\]

Согласно условию задачи,

\[\label{eq:inf_bd_02} p + q = s.\]

Поскольку \(b > \sqrt{n}\), из уравнения \eqref{eq:inf_bd_01} следует, что \(n = p \cdot b + q \geqslant p \cdot b > p^2\), откуда получаем \(p < \sqrt{n}\). Таким образом можно провести полный перебор по старшей цифре \(p\). Из уравнений \eqref{eq:inf_bd_01} и \eqref{eq:inf_bd_02} следует, что \(b = \dfrac{n - s}{p} + 1\), поэтому \(b\) однозначно определяется по \(p\). Наконец, для такого \(b\) необходимо проверить, выполняется ли условие \(f(b, n) = s\).

Общая сложность алгоритма составляет \(\mathcal{O}(\sqrt{n})\), что позволяет получить максимальный балл.

Пример программы-решения

Ниже представлено решение на языке Python.

Python
def sum_digit(b, n):
    if n < b:
        return n
    return sum_digit(b, n // b) + n % b
 
N = int(input())
S = int(input())
 
if S > N:
    print(-1)
elif S == N:
    print(N + 1)
else:
    sqrt = int(pow(N, 0.5))
    for b in range(2, sqrt + 1):
        if sum_digit(b, N) == S:
            print(b)
            quit()
    for k in reversed(range(1, sqrt + 1)):
        if (N - S) % k == 0:
            b = (N - S) // k + 1
            if sum_digit(b, N) == S:
                print(b)
                quit()
    print(-1)
Задача 1.5.(25 баллов)
Исследование космоса

Имя входного файла: стандартный ввод или input.txt.

Имя выходного файла: стандартный вывод или output.txt.

Ограничение по времени выполнения программы: 3 с.

Ограничение по памяти: 256 Мбайт.

Условие

Для наблюдения за космосом нужно подняться как можно выше над уровнем моря.

Территория для наблюдения представляет собой полосу шириной \(w\), разбитую на единичные квадраты. В \(i\)-м из них находится столбец земли высотой \(h_i\). Можно добавить не более \(n\) клеток с песком, чтобы поднять территорию как можно выше. Однако песок нестабилен, и клетку с песком можно разместить только при условии, что клетка под ней, а также клетки по диагонали слева снизу и справа снизу заполнены землей или песком.

Определите максимальную высоту над уровнем моря, которую можно создать для наблюдения за космосом.

Формат входных данных

Первая строка содержит два целых числа \(w\) (\(1 \leqslant w \leqslant 100\,000\)) — ширина территории и \(n\) (\(0 \leqslant n \leqslant 10^9\)) — максимальное количество добавляемых клеток песка.

Следующие \(w\) строк содержат одно целое число \(h_i\) — высоту \(i\)-го столбца земли (\(1 \leqslant h_i \leqslant 10^9\)).

Формат выходных данных

Определите максимальную высоту над уровнем моря, которую можно создать для наблюдения за космосом.

Тестовые данные

Номер тестаСтандартный вводСтандартный вывод
1
8 5
3
3
3
2
3
1
2
4
5
2
3 10
1
2
1
2

Решение

Найдем ответ бинарным поиском по ответу следующим образом. Предположим, что сможем получить высоту \(h\). Тогда посчитаем, сколько понадобится песка, чтобы ее построить. Если есть необходимое количество, такая высота горы устраивает.

Чтобы по данному \(h\) определить необходимое количество песка, переберем всевозможные \(i\), где может находиться вершина горы. Чтобы считать количество песка быстрее, заведем три вспомогательных массива: массив префиксных сумм \({psum}\) (для быстрого подсчета суммы высот каменных столбов), массив \({left}\) и массив \({right}\). Два последних массива понадобятся пересчитывать для каждого \(h\).

Массив \({left}\) — это такой массив, что \({left}[i]\) — координата левой границы насыпи из песка, если вершина насыпи высоты \(h\) находится на координате \(i\). Будем строить его следующим образом: для каждой координаты \(i\) посчитаем, для какой координаты \({sfrom}\) она может быть левой границей насыпи (чтобы \({left}[{sfrom}] = i\)). Если будем перебирать \(i\) слева, то для каждой координаты \({sfrom}\) значение \({left}[{sfrom}]\) будет максимальным, что и требуется. Аналогично построим массив \({right}\) — координаты правых границ насыпей.

После этого остается перебрать всевозможные координаты вершины и для каждой посчитать размер горы высоты \(h\) (учитывая камни). Это можно сделать по формуле, так как известно, где каждая гора начинается (по массиву \({left}\)) и заканчивается (по массиву \({right}\)). Затем остается вычесть количество камней в полученной горе (с помощью \({psum}\)) и найти минимум среди полученных значений.

Пример программы-решения

Ниже представлено решение на языке Python.

Python
import sys

inf = int(2e18)
N = 123456

h = [0] * N
ev = [[] for _ in range(N)]
ans = [0] * N
sum = [0] * N

def main():
    n, m = map(int, sys.stdin.readline().split())
    for i in range(n):
        h[i] = int(sys.stdin.readline().strip())
    
    low = 0
    for i in range(n):
        low = max(low, h[i])
    
    high = int(1.01e9)
    while low < high:
        mid = (low + high + 1) // 2
        for i in range(n):
            ans[i] = 0
        
        for rot in range(2):
            sum[0] = h[0]
            for i in range(1, n):
                sum[i] = sum[i - 1] + h[i]
            
            for i in range(n):
                ev[i].clear()
            
            for i in range(n):
                j = i + mid - h[i]
                if j < n:
                    ev[j].append(i)
            
            mx = -1
            for i in range(n):
                for j in range(len(ev[i])):
                    mx = max(mx, ev[i][j])
                if mx >= 0:
                    from_val = mid - 1
                    to = mid - (i - mx) + 1
                    ans[i] += (to + from_val) * (from_val - to + 1) // 2
                    ans[i] -= (sum[i - 1] - sum[mx])
                else:
                    ans[i] += inf
            
            for i in range(n // 2):
                h[i], h[n - i - 1] = h[n - i - 1], h[i]
                ans[i], ans[n - i - 1] = ans[n - i - 1], ans[i]
        
        found = False
        for i in range(n):
            ans[i] += mid - h[i]
            if ans[i] <= m:
                found = True
                break
        
        if found:
            low = mid
        else:
            high = mid - 1
    
    print(low)

if __name__ == "__main__":
    main()
text slider background image text slider background image
text slider background image text slider background image text slider background image text slider background image