Ответы на Яндекс олимпиаду по информатике 2023: подробное решение задач

Правильная подготовка к олимпиаде по информатике — это ключ к успеху. И, конечно же, ответы на задачи являются неотъемлемой частью этой подготовки. Именно поэтому мы предлагаем Вам подробное решение всех задач Яндекс олимпиады по информатике 2023.

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

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

Так что не откладывайте на завтра, подготовьтесь к олимпиаде сейчас с нашими подробными решениями!

Задача №1: «Разбиение строки»

Условие

Дана строка S длиной не более 10^5 символов. Необходимо разбить ее на максимальное число подстрок таким образом, чтобы в каждой подстроке каждая буква встречалась ровно один раз. Найдите максимальное число подстрок.

Решение

Для решения задачи необходимо пройтись по строке символ за символом и проверять, есть ли данный символ в текущей подстроке, если нет, то можно добавить его в текущую подстроку. Однако, если данный символ уже содержится в текущей подстроке, то нужно закрыть текущую подстроку и начать создание следующей.

Для эффективного поиска повторяющихся символов можно использовать множество (set). Если встретился повторяющийся символ, то закрываем текущую подстроку и создаем новую. Максимальное число подстрок – это количество закрытых подстрок, так как в каждой подстроке каждая буква встречается ровно один раз.

Пример кода

s = input()

current_substring = set()

count = 0

for c in s:

if c in current_substring:

count += 1

current_substring = set()

current_substring.add(c)

print(count + 1)

Задача №2: «Калькулятор максимума»

Условие задачи

Даны два числа a и b. Требуется написать программу, которая определяет, какое из них больше и выводит на экран его значение.

Алгоритм решения

Для решения задачи рекомендуется воспользоваться стандартными функциями языка программирования. Одним из способов является использование функции max(a, b), которая возвращает максимальное значение из двух переданных ей аргументов.

Для того, чтобы использовать данную функцию, необходимо объявить переменные a и b, присвоить им значения и вызвать функцию max(a, b), передав ей в качестве аргументов значения переменных a и b.

Пример кода:

a = 10;

b = 5;

print(max(a, b));

Примеры входных и выходных данных

Входные данные: a = 10, b = 5. Выходные данные: 10.

Входные данные: a = 6, b = 10. Выходные данные: 10.

Входные данные: a = 8, b = 8. Выходные данные: 8.

Задача №3: «Длинный палиндром»

Условие задачи

Дана строка, состоящая из строчных латинских букв. Необходимо найти самый длинный палиндром — подстроку, которая читается одинаково в обоих направлениях.

Решение задачи

Для решения можно использовать алгоритм Манакера, который позволяет находить все палиндромы и их длины за линейное время. Суть алгоритма заключается в том, что для каждой позиции i строки строятся симметрические позиции относительно центра текущего палиндрома, которые уже были обработаны. Таким образом, находясь на позиции i, мы можем использовать ранее найденные палиндромы для ускорения поиска.

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

Пример реализации на Python

def manacher(s):

n = len(s)

d1, d2 = [0] * n, [0] * n

l, r, k = 0, -1, 0

for i in range(n):

if i<=r:

k = min(d1[l+r-i], r-i)

while i+k=0 and s[i+k]==s[i-k]:

k += 1

d1[i] = k

if i+k-1 > r:

l, r = i-k+1, i+k-1

l, r, k = 0, -1, 0

for i in range(n):

if i<=r:

k = min(d2[l+r-i+1], r-i+1)

while i+k-1=0 and s[i+k-1]==s[i-k]:

k += 1

d2[i] = k

if i+k-1 > r:

l, r = i-k, i+k-1

return [2*d1[i]-1 for i in range(n)], [2*d2[i] for i in range(n)]

def find_longest_palindrome(s):

n = len(s)

if n == 0:

return ""

s_new = "#" + "#".join(s) + "#"

d1, d2 = manacher(s_new)

max_len, center = max((len1, i) for i, len1 in enumerate(d1))

start = (center - max_len) // 2

return s[start:start + max_len]

Задача №4: «Численный угадыватель»

Условие задачи

Дано натуральное число N и массив A длины N. Необходимо реализовать функцию, которая будет угадывать число, загаданное пользователем, путем задавания вопросов и сравнивания ответов с элементами массива A.

Вопросы должны иметь формат: «Ваше число больше/меньше/равно [элементу массива]?», ответы пользователя — «Да» или «Нет».

Функция должна возвращать загаданное число и количество заданных вопросов.

Решение задачи

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

Алгоритм бинарного поиска:

  • Устанавливаем левую и правую границы поиска, равные 0 и N-1 соответственно.
  • Пока левая граница меньше или равна правой:
    • Находим средний индекс элемента массива: mid = (left + right) / 2.
    • Сравниваем искомое число с элементом массива A[mid].
    • Если искомое число меньше A[mid], то устанавливаем правую границу поиска в mid-1.
    • Если искомое число больше A[mid], то устанавливаем левую границу поиска в mid+1.
    • Если искомое число равно A[mid], то возвращаем mid.

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

Функция должна возвращать найденное число и количество заданных вопросов.

Пример реализации функции на Python

Входные данные Выходные данные
N = 10, A = [2, 4, 7, 9, 15, 18, 20, 24, 27, 30] угаданное число: 7, количество заданных вопросов: 2
N = 8, A = [2, 4, 7, 9, 15, 18, 20, 24] угаданное число: 18, количество заданных вопросов: 3

def number_guesser(N, A):

left = 0

right = N - 1

questions = 0

while left <= right:

mid = (left + right) // 2

guess = A[mid]

questions += 1

answer = input(f"Ваше число больше/меньше/равно {guess}? ")

if answer == "Да":

left = mid + 1

elif answer == "Нет":

right = mid - 1

elif answer == "Равно":

return guess, questions

Задача №5: «Сортировка фильмов»

Условие задачи

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

Решение задачи

Для решения этой задачи можно использовать стандартную сортировку Python и определенную функцию для задания ключа сортировки. Сначала мы отсортируем список фильмов по году выпуска, используя функцию sorted () и параметр key, который задает функцию, которая принимает элемент списка и возвращает значение для сортировки. Затем мы снова используем sorted () для сортировки по имени фильма с помощью lambda-функции, после чего мы дополнительно сортируем по возрастанию рейтинга, используя параметр key.

# сортировка по году выпуска

movies.sort(key=lambda x: x[1])

# сортировка по имени фильма

movies = sorted(movies, key=lambda x: x[0].lower())

# сортировка по рейтингу для одинакового года выпуска и названия фильма

movies = sorted(movies, key=lambda x: x[2])

Теперь список фильмов отсортирован в порядке, описанном в условии задачи.

Добавить комментарий