Предметный тур. Информатика. 3 этап
Имя входного файла: стандартный ввод или input.txt.
Имя выходного файла: стандартный вывод или output.txt.
Ограничение по времени выполнения программы: 5 с.
Ограничение по памяти: 256 Мбайт.
Среди списка из \(N\) различных целых чисел выберите ровно три таких, чтобы в них встречались все цифры от \(0\) до \(9\) (возможно несколько раз). В случае существования нескольких вариантов ответа допускается вывести любой.
Формат входных данных
В первой строке указано количество чисел. Во второй строке — целые числа, записанные через пробел. Количество чисел в каждой строке не более \(30\), сами числа по модулю не превышают \(10^9\).
Формат выходных данных
Выведите три числа, упорядоченных по возрастанию, разделенных пробелом.
Тестовые данные
| Номер теста | Стандартный ввод | Стандартный вывод |
|---|---|---|
1 |
6 1309 1584 1180 1762 1727 1152 |
1309 1584 1762 |
Сначала предстоит получить комбинации из троек чисел, что можно сделать, используя вложенный цикл или специальные библиотеки комбинаторики. Затем для каждой комбинации посчитать наличие каждой из 10 цифр, для чего удобно использовать множество, добавляя в него по одному символу (цифре). Также можно делить каждое число в комбинации на разряды и учитывать встретившиеся цифры в массиве.
В случае, когда найдены все цифры в комбинации — прервать цикл.
Пример программы-решения
Ниже представлено решение на языке Python.
# Все цифры собрать
from itertools import combinations
numbers = map(int, input().split(' '))
for comb in list(combinations(numbers, 3)):
combstr = str(comb)[1:-1].replace(', ', ' ')
if len(set(combstr.replace(' ', ''))) == 10:
print(" ".join(map(str, sorted(comb))))
break
Имя входного файла: стандартный ввод или input.txt.
Имя выходного файла: стандартный вывод или output.txt.
Ограничение по времени выполнения программы: 5 с.
Ограничение по памяти: 256 Мбайт.
Программист Петя осваивает работу с графическими примитивами. Его программа рисует множество цветных прямоугольников, координаты (левого верхнего и правого нижнего углов) и цвет (обозначен целым положительным числом) известны. Так как прямоугольники могут быть нарисованы поверх друг друга, они частично или полностью перекрываются.
Напишите программу, которая должна определить, какую площадь занимает каждый цвет на экране в итоговой картинке. Координаты прямоугольников не превышают по модулю \(500\), число прямоугольников не более \(50\). Фоновый цвет не учитывается. В ответе указывайте только цвета с ненулевой площадью (какие-то прямоугольники могут оказаться полностью скрыты).

Формат входных данных
В первой строке указано число прямоугольников. В каждой следующей строке записаны \(5\) целых чисел: цвет, координаты (\(X1\), \(Y1\)) левого верхнего угла и (\(X2\), \(Y2\)) правого нижнего прямоугольника. Числа разделены пробелом. Порядок описания прямоугольников определяет порядок их отрисовки.
Формат выходных данных
В каждой строке указан цвет и занятая им площадь (два целых числа, разделенных пробелом). Строки упорядочите в порядке возрастания номера цвета (целого числа).
Тестовые данные
| Номер теста | Стандартный ввод | Стандартный вывод |
|---|---|---|
1 |
3 1 1 6 5 2 2 2 5 7 1 3 0 4 8 2 |
1 5 2 10 3 16 |
Определите границы прямоугольной области, в которой располагаются прямоугольники. Для этой области постройте сетку, — двумерный массив — в элементах которой учитываются цвета каждой клетки. Последовательно для каждого прямоугольника «закрашивайте» занятую им площадь, после чего останется только посчитать число элементов для каждого цвета.
Пример программы-решения
Ниже представлено решение на языке Python.
import sys
rects = []
for line in sys.stdin:
rects.append(list(map(int, line.split())))
left, right, top, bottom = \
(min([min(x1, x2) for (color, x1, y1, x2, y2) in rects ])), \
(max([max(x1, x2) for (color, x1, y1, x2, y2) in rects ])), \
(max([max(y1, y2) for (color, x1, y1, x2, y2) in rects ])), \
(min([min(y1, y2) for (color, x1, y1, x2, y2) in rects ])) \
width = right-left; height = top-bottom
matrix = [[-1 for _ in range(width+1)] for _ in range (height+1)]
for (color, x1, y1, x2, y2) in rects:
for y in range(y1-y2):
for x in range(x2-x1):
matrix[y1-y-bottom][x1+x-left] = color
from collections import Counter
count_colors = Counter([item for row in matrix for item in row])
for color in sorted(count_colors)[1:]:
print(f"{color} {count_colors[color]}")
Имя входного файла: стандартный ввод или input.txt.
Имя выходного файла: стандартный вывод или output.txt.
Ограничение по времени выполнения программы: 1 с.
Ограничение по памяти: 64 Мбайт.
Если делить \(1\) на целое число, то часто получается периодическая десятичная дробь. В случае бесконечной периодической дроби длина периода ограничена величиной делителя. Для заданного делителя \(N\) рассчитайте, какое число \(d~ (2 < d < N)\) даст при делении наибольший период дроби. Если таких чисел будет несколько, выведите любое. \(N\) не превышает \(10000\). Указание: используйте навык деления числа столбиком и обратите внимание на последовательность остатков от деления.
Примеры деления \(1\) на числа от \(2\) до \(9\): \[\begin{gather} 1/2= 0,5;\\ 1/3= 0,(3);\\ 1/4= 0,25;\\ 1/5= 0,2;\\ 1/6= 0,1(6);\\ 1/7= 0,(142857);\\ 1/8= 0,125;\\ 1/9= 0,(1);\\ 1/10= 0,1. \end{gather}\]
Формат входных данных
Одно целое число \(N\).
Формат выходных данных
Одно целое число \(d\).
Тестовые данные
| Номер теста | Стандартный ввод | Стандартный вывод |
|---|---|---|
1 |
1000 |
983 |
Для решения необходимо использовать алгоритм деления числа «столбиком». При таком делении на каждом шаге образуется остаток, число различных остатков ограничено величиной делителя. Создайте массив логических значений длиной \(d\), затем в процессе деления отмечайте в массиве какие остатки встретились. При повторе — прервите цикл, посчитайте число полученных остатков (элементов массива со значением true), это число и будет ответом.
Пример программы-решения
Ниже представлено решение на языке Kotlin.
import java.util.Scanner
fun findLongestRecurringDecimal(n: Int): Int {
var maxLength = 0
var number = 0
for (d in 2 until n) {
val remainder = BooleanArray(d) { false } //значения по умолчанию
var numerator = 1
var position = 0
while (numerator != 0 && !remainder[numerator]) {
remainder[numerator] = true
numerator = (numerator * 10) % d
position++
}
if (position - 1 > maxLength) {
maxLength = position - 1
number = d
}
}
return number
}
fun main() {
val n = Scanner(System.`in`).nextInt()
println(findLongestRecurringDecimal(n))
}
Имя входного файла: стандартный ввод или input.txt.
Имя выходного файла: стандартный вывод или output.txt.
Ограничение по времени выполнения программы: 1 с.
Ограничение по памяти: 64 Мбайт.
В некоторых узлах прямоугольной решетки размера \(W\times H\) расположены зеркала, нумерация узлов идет с левого верхнего угла \((0, 0)\) до правого нижнего \((W, H)\). Зеркало отражает с обеих сторон и может иметь два положения: «/» и «\», обозначенных соответствующими спецсимволами. Лазерный луч направлен вверх, излучается из точки \((X_1, Y_1)\). Рассчитайте точку \((X_2, Y_2)\) выхода луча из решетки (расположенную на ее границе). Число зеркал и размеры поля не превышают \(500\).
Формат входных данных
Первая строка: целые числа \(W\), \(H\) — размеры решетки, число \(N\) зеркал.
Вторая строка — два целых числа — точка \((X_1, Y_1)\) входа луча в решетку.
Следующие далее \(N\) строк с координатами \((X, Y)\) каждого зеркала — целые числа, разделенные пробелом, далее через пробел символ «/» или «\», указывающий ориентацию зеркала.
Формат выходных данных
Два целых числа — точка \((X_2, Y_2)\) выхода луча из решетки — целые числа, разделенные пробелом.
Тестовые данные
| Номер теста | Стандартный ввод | Стандартный вывод |
|---|---|---|
1 |
8 5 9 1 5 1 1 / 3 1 \ 4 1 / 7 1 / 2 2 / 3 2 / 7 3 / 2 4 \ 6 4 / |
6 0 |
Размеры тестовых данных позволяют использовать пошаговый алгоритм, отслеживая путь лазерного луча с учетом направления движения. На каждом шаге проверяйте достижение границы поля (конец пути) или наличие зеркала. Смену направления луча на месте зеркала удобно выполнить, используя словарь. Нет необходимости создавать сетку в виде двумерного массива, достаточно создать словарь с ключом в формате \((X, Y)\), содержащем сведения о зеркалах.
Пример программы-решения
Ниже представлено решение на языке Python.
# laser beam and mirrors solution
from enum import Enum
class Direction(Enum):
UP = 1; RIGHT = 2; DOWN = 3; LEFT = 4
rotate = { '/': {
Direction.RIGHT: Direction.UP,
Direction.LEFT: Direction.DOWN,
Direction.DOWN: Direction.LEFT,
Direction.UP: Direction.RIGHT },
'\\': {
Direction.RIGHT: Direction.DOWN,
Direction.LEFT: Direction.UP,
Direction.DOWN: Direction.RIGHT,
Direction.UP: Direction.LEFT }
}
w, h, n_mirrors = map(int, input().split())
x, y = map(int, input().split())
mirrors = {}
for n in range(n_mirrors):
mx, my, mtype = input().split()
mirrors[(int(mx), int(my))] = mtype
def step_forward():
global x, y
match dir:
case Direction.RIGHT: x += 1
case Direction.LEFT: x -= 1
case Direction.UP: y -= 1
case Direction.DOWN: y += 1
dir = Direction.UP # default direction
step_forward() # entering the field
while (x != 0 and x != w and y != 0 and y != h):
#print(x, y, dir) # debug
if (x, y) in mirrors:
mirror_type = mirrors[(x, y)]
dir = rotate[mirror_type][dir]
step_forward()
print(x, y) # finish point
Имя входного файла: стандартный ввод или input.txt.
Имя выходного файла: стандартный вывод или output.txt.
Ограничение по времени выполнения программы: 5 с.
Ограничение по памяти: 64 Мбайт.
В известной кодировке символов ASCII каждой букве и спецсимволу соответствует определенное число (пробелу — 32, a — 97, k — 107). Во времена начала IT-индустрии популярным способом шифрования текстов была операция XOR (исключающее «или»). К исходному тексту побуквенно, циклически применялась операция XOR для определенного слова (ключа).
Преимущество операции XOR в том, что при повторном использовании того же ключа для шифрованного текста восстанавливается исходный текст. Например, \(65\) XOR \(42\) = \(107\), тогда \(107\) XOR \(42\) = \(65\). К сожалению, этот метод непрактичен для большинства пользователей. Если ключ короче сообщения, он циклически повторяется на протяжении всего сообщения.
Исходный текст — на английском языке, не содержащий спецсимволов, кроме пробелов и знаков препинания длиной от \(1000\) до \(10000\) символов. Гарантируется, что в исходном тексте каждого тестового набора присутствуют слова: this, the, of, by, to, is. Текст зашифрован ключом — трехбуквенным сочетанием в нижнем регистре, все буквы различны (например, xor). Зашифрованный текст дан в виде набора чисел — кодов символов, чтобы избежать ошибок при чтении непечатных символов. Подберите ключ и расшифруйте текст, проверив выполнение условий, описанных выше.
Формат входных данных
Одна строка из чисел (кодов символов), разделенных пробелом.
Формат выходных данных
Три буквы ключа шифрования без разделителей.
Тестовые данные
| Номер теста | Стандартный ввод | Стандартный вывод |
|---|---|---|
1 |
36,22,80,0,0,4,23,25,19,17,88,4,4,19,21,11,88,22,23,23,29,69, 12,24,0,88,25,11,12,2,10,28,5,6,12,25,10,22,80,10,30,80,10,22, 21,69,23,22,69,61,5,9,29,2,66,11,80,8,23,3,17,88,19,0,20,21,7, 10,17,17,29,20,69,8,17,21,29,2,22,84,80,71,60,21,69,11,5,8,21, 25,22,88,3,0,10,25,0,10,5,8,88,2,0,27,25,21,10,31,6,25,2,16,21, 82,69,35,63,11,88,4,13,29,80,22,13,29,22,88,31,3,88,3,0,10,25, 0,11,80,10,30,80,23,29,19,12,8,2,10,27,17,9,11,45,95,88,57,69, 16,17,19,29,80,23,29,19,0,22,4,9,1,80,3,23,5,11,28,92,69,9,5, 12,12,21,69,13,30,0,0,0,0,27,4,0,28,28,28,84,80,4,22,80,0,20, 21,2,25,30,17,88,21,29,8,2,0,11,3,12,23,30,69,30,31,23,88,4,13, 29,80,0,22,4,12,10,21,69,11,5,8,88,31,3,88,4,13,17,3,69,11,21, 23,17,21,22,88,65,69,83,80,84,87,68,69,83,80,84,87,73,69,83,80, 84,87,65,83,88,91,69,29,4,6,86,92,69,15,24,12,27,24,69,28,21, 21,29,30,1,11,80,10,22,80,17,16,21,69,9,5,4,28,2,4,12,5,23,29, 80,10,30,80,17,16,21,69,27,25,23,27,28,0,84,80,22,23,80,17,16, 17,17,88,25,3,88,4,13,29,80,17,10,5,0,88,3,16,21,80,10,30,80, 17,16,25,22,88,3,0,10,25,0,11,80,12,11,80,10,26,4,4,17,30,0,28, 92,69,30,2,10,21,80,12,12,80,4,12,80,10,22,19,0,88,4,13,29,80, 20,13,17,1,10,17,17,13,2,0,88,31,3,88,4,13,29,80,6,17,2,6,20, 21,69,30,31,9,20,31,18,11,94,69,54,17,8,29,28,28,84,80,44,88, 24,4,14,21,69,30,31,16,22,20,69,12,24,4,12,80,17,16,21,69,11,5, 8,88,31,3,88,4,13,17,3,69,11,21,23,17,21,22,88,25,22,88,17,69, 11,25,29,12,24,69,8,17,23,12,80,10,30,80,17,16,21,69,11,1,16, 25,2,0,88,31,3,88,4,13,29,80,21,29,2,12,21,21,17,29,2,69,23,22, 69,12,24,0,88,19,12,10,19,9,29,80,18,16,31,22,29,80,1,17,17,8, 29,4,0,10,80,12,11,80,84,67,80,10,10,80,7,1,80,21,13,4,17,17, 30,2,88,4,13,29,80,22,13,29,69,23,22,69,12,24,12,11,80,22,29,2, 12,29,3,69,29,1,16,25,28,69,12,31,69,11,92,69,17,4,69,16,17,22, 88,4,13,29,80,23,25,4,12,23,80,22,9,2,17,80,70,76,88,29,16,20, 4,12,8,28,12,29,20,69,26,9,69,11,80,17,23,80,84,88,31,3,88,4, 13,29,80,21,29,2,12,21,21,17,29,2,69,12,31,69,12,24,0,88,20,12, 25,29,0,12,21,23,86,80,44,88,7,12,20,28,69,11,31,10,22,80,22, 16,31,18,88,4,13,25,4,69,12,24,0,88,3,16,21,80,10,30,80,17,16, 25,22,88,3,0,10,25,0,11,80,17,23,80,7,29,80,4,8,0,23,23,8,12, 21,17,17,29,28,28,88,65,75,78,68,81,65,67,81,72,70,83,64,68,87, 74,70,81,75,70,81,67,80,4,22,20,69,30,2,10,21,80,8,13,28,17,17, 0,9,1,25,11,31,80,17,16,25,22,88,30,16,21,18,0,10,80,7,1,80,22, 17,8,73,88,17,11,28,80,17,16,21,11,88,4,4,19,25,11,31,80,17,16, 21,69,11,1,16,25,2,0,88,2,10,23,4,73,88,4,13,29,80,11,13,29,7, 29,2,69,75,94,84,76,65,80,65,66,83,77,67,80,64,73,82,65,67,87, 75,72,69,17,3,69,17,30,1,29,21,1,88,0,23,23,20,16,27,21,1,84, 80,18,16,25,6,16,80,0,0,0,23,29,3,22,29,3,69,12,24,0,88,0,0,10, 25,8,29,4,0,10,80,10,30,80,4,88,19,12,10,19,9,29,80,18,16,31, 22,29,80,1,17,17,8,29,4,0,10,80,12,11,80,84,86,80,35,23,28,9, 23,7,12,22,23,69,25,23,4,17,30,69,12,24,0,88,3,4,21,21,69,11,4, 0,8,3,69,26,9,69,15,24,12,27,24,69,49,80,13,25,20,69,25,2,23, 17, 6,0,28,80,4,12,80,17,16,25,22,88,3,16,21,92,69,49,80,13,25, 6,0,88,20,12,11,19,10,14,21,23,29,20,69,12,24,4,12,80,17,16,21, 69,11,5,8,88,31,3,88,4,13,29,80,22,29,2,12,29,3,69,73,80,78,88, 65,74,73,70,69,83,80,84,87,72,84,88,91,69,73,95,87,77,70,69,83, 80,84,87,70,87,77,80,78,88,21,17,27,94,69,25,28,22,23,80,1,29, 0,0,22,20,22,88,31,11,88,4,13,29,80,20,13,17,1,10,17,17,13,2,0, 88,31,3,88,4,13,29,80,6,17,2,6,20,21,75,88,62,4,21,21,9,1,92, 69,12,24,0,88,3,16,21,80,10,30,80,17,16,25,22,88,29,16,20,4,12, 8,28,12,29,20,69,26,9,69,65,64,69,31,25,19,29,3,69,12,24,0,88, 18,12,9,5,4,28,2,4,12,21,69,80,22,10,13,2,17,16,80,21,23,7,0, 10,89,69,23,22,69,12,24,0,88,19,12,10,19,16,21,22,0,10,21,11, 27,21,69,23,22,69,12,24,0,88,0,0,10,25,8,29,4,0,10,80,10,30,80, 4,88,19,12,10,19,9,29,80,18,16,31,22,29,80,1,17,17,8,29,4,0,10, 80,12,11,80,84,86,80,36,22,20,69,26,9,69,11,25,8,17,28,4,10,80, 23,29,17,22,23,30,12,22,23,69,49,80,13,25,6,0,88,28,12,19,21, 18,17,3,0,88,18,0,29,30,69,25,18,9,29,80,17,23,80,1,29,4,0,10, 29,12,22,21,69,12,24,0,88,3,16,21,3,69,23,22,69,12,24,0,88,3, 16,26,3,0,9,5,0,22,4,69,11,21,23,17,21,22,88,25,11,88,7,13,17, 19,13,88,4,13,29,80,0,0,0,10,22,21,11,12,3,69,25,2,0,88,21,19, 29,30,69,22,5,8,26,21,23,11,94 |
exp |
Сгенерируйте все варианты ключей из трех букв английского алфавита и считайте зашифрованный текст, данный в виде кодов символов. Далее для каждого ключа примените циклически операцию XOR для символов зашифрованного текста с номерами 1, 2, 3, затем 4, 5, 6 и т. д. Преобразуйте набор чисел в символы. Полученный набор символов проверьте на выполнение двух условий:
- все символы принадлежат к множеству печатных (
printable); - все указанные в условии слова присутствуют в расшифрованном тексте.
Подходящий под условия код и будет ответом на задачу.
Пример программы-решения
Ниже представлено решение на языке Python.
from itertools import count, product
from string import ascii_lowercase as letters, printable
from operator import xor
cipher = list(map(int, input().split(',')))
allowed = set(printable[:94] + ' ')
words = ["the", "of", "is", "by", "to", "this"]
pass_gen = product(map(ord, letters), repeat=3)
for password in pass_gen:
plain, rep = "", (password[i % 3] for i in count())
for char in map(chr, map(xor, cipher, rep)):
if char not in allowed: break
plain += char
else:
if all(word in plain for word in words):
print("".join(map(chr, password)))
break # password found

