Организационный комитет Международной олимпиады Белорусско-Российского университета по программированию для школьников BRU Python Blitz публикует условия задач и лучшие решения с указанием авторства.
Задача Blitz01. Напишите функцию palindrom(a), которая возвращает True, если целое число a является палиндромом, False, если не является.
Решение Сивко Тимура Олеговича, ГУО "Гимназия №1 им. академика Ф.Е. Карского г. Гродно
def palindrom(a):
return str(a)[::-1] == str(a)
Задача Blitz02. Напишите функцию palindroms(a), на вход которой подается строка, содержащая некоторое количество натуральных чисел, разделенных символом “пробел”, которая возвращает количество палиндромов в указанной строке
Решение Сивко Тимура Олеговича, ГУО "Гимназия №1 им. академика Ф.Е. Карского г. Гродно
def palindroms(a):
return len([b for b in a.split() if b[::-1] == b])
Задача Blitz03. Напишите функцию swap(a), на вход которой подается строка, содержащая два натуральных числа, разделенных символом “пробел”, которая возвращает строку, в которой эти же числа переставлены друг с другом и разделены символом “пробел”.
Решение Сивко Тимура Олеговича, ГУО "Гимназия №1 им. академика Ф.Е. Карского г. Гродно
def swap(a):
return ' '.join(a.split()[::-1])
Задача Blitz04. Напишите функцию shift_right(a), на вход которой подается строка, содержащая три натуральных числа, разделенных символом “пробел”, которая возвращает строку, содержащую эти же три натуральных числа, разделенных символом “пробел”, циклически сдвинутых право. Например, shift_right(“123 456 789”) возвращает строку 789 123 456.
Авторское решение
def shift_right(a):
return(" ".join(a.split()[2:]+a.split()[:2]))
Задача Blitz05. Напишите функцию rotate(a), на вход которой подается натуральное число a, которая возвращает число, представляющее собой число a, записанное в обратном порядке следования цифр.
Авторское решение
def rotate(a):
return int(str(a)[::-1])
Задача Blitz06. Напишите функцию rotate_all(a), на вход которой подается строка, содержащая натуральные числа, разделенные символом “пробел”, которая возвращает строку, содержащую те же числа в том же порядке, но записанные в обратном порядке следования цифр.
Лучшее решение (Сивко Тимур Олегович, ГУО "Гимназия №1 им. академика Ф.Е. Карского г. Гродно)
def rotate_all(a):
return ' '.join([b[::-1] for b in a.split()])
Задача Blitz07. Напишите функцию div357(a), которая выдает количество чисел, делителями которых одновременно являются 3, 5, 7 из диапазона 1:a.
Авторское решение
def div357(a):
return a//(3*5*7)
Задача Blitz08. Для передачи сообщений на некотором языке, в алфавит которого входят только буквы А, Б, В, Г, Д разработана специальная система шифрования – шифр А-1, Б-2, В-11, Г-12, Д-112. Напишите функцию decode(a), которая по входящему коду (натуральное число, состоящее из цифр 1 и 2) возвращает количество возможных вариантов декодированного слова.
Например, коду 11 могут соответствовать два варианта- слова АА и В.
Авторское решение
def recurro(a):
voc = ['1', '2', '11', '12', '112']
p = 0
if len(a) == 0:
return p+1
for letter in voc:
if a.find(letter) == 0:
if len(a)>1:
p+=recurro(a[len(letter):])
else:
p+=1
return p
def decode(a):
s = recurro(str(a))
return s
Задача Blitz09. Для управления роботизированной установкой требуется программа – строка, состоящая из буквенно-цифровых пар, где буква указывает направление перемещения (N – север, S – юг, E – восток, W – запад) и дистанцию в метрах (целое число), на которую перемещается робот. Вот пример такой программы: S10W5, при выполнении которой робот сначала переместится на 10 метров на юг, а затем на 5 метров на запад.
Требуется написать функцию distance(a), которая вычислит дистанцию в метрах, на которую робот удалился из стартовой точки при выполнении программы, заданной строкой a.
Решение Сивко Тимура Олеговича, ГУО "Гимназия №1 им. академика Ф.Е. Карского г. Гродно
import re
def distance(a):
return round(((sum(map(int, re.findall(r'N(\d+)', a))) - sum(map(int, re.findall(r'S(\d+)', a)))) ** 2 +
(sum(map(int, re.findall(r'E(\d+)', a))) - sum(map(int, re.findall(r'W(\d+)', a)))) ** 2) ** 0.5, 2)
Задача Blitz10. Напишите функцию digitscount(a), которая возвращает количество цифр в строке a.
Авторское решение
import re
def digitscounter(a):
return len(re.findall("[0-9]",a))
На вход программы подается 2*n действительных чисел (n – натуральное число, n>=4) через пробел в формате
x1 x2 x3 x4 x5 x6 x7 x8…
Задача Blitz11. Напишите программу, которая определяет, будут ли отрезки [x1, x2], [x3, x4], …, [xn-1, xn] вложены друг в друга. В случае, если все отрезки являются вложенными, программа должна напечатать YES, в противном случае NO.
Авторское решение
a = input()
z = a.split(" ")
left = 1
right = 1
for i in range(1, int(len(z)/2)):
left*=float(z[2*(i-1)])<=float(z[2*i])
right*=float(z[2*(i-1)+1])>=float(z[2*i+1])
print("YES" if left*right else "NO")
Задача Blitz12. Напишите функцию sqr(a), которая будет возвращать квадрат числа a.
Авторское решение
def sqr(a):
return a*a
Задача Blitz13. На вход программы подаются четыре числа – координаты точек на плоскости (x1, y1), (x2, y2) в формате x1 y1 x2 y2 (через пробел).
Напишите программу, которая печатает расстояние между точками, округленное до двух знаков после запятой.
Решение Сивко Тимура Олеговича, ГУО "Гимназия №1 им. академика Ф.Е. Карского г. Гродно
x1, y1, x2, y2 = map(int, input().split())
print(round(((x1 - x2)**2 + (y1 - y2)**2)**0.5, 2))
Задача Blitz14. Напишите функцию sgn(x), которая возвращает 1, если x>0, -1, если x<0, 0, если x=0.
Авторское решение
def sgn(x):
return int(abs(x)/x) if x!=0 else 0
Задача Blitz15. Напишите функцию fracshort(a), на вход которой подается строка вида “m/n”, где m и n – натуральные числа, которая возвращает строку вида “m/n=p/q”, где p/q – дробь, полученная в результате сокращения дроби m/n.
Решение Сивко Тимура Олеговича, ГУО "Гимназия №1 им. академика Ф.Е. Карского г. Гродно
import math
def fracshort(a):
m, n = map(int, a.split('/'))
gcd = math.gcd(m, n)
return f'{m}/{n}={m//gcd}/{n//gcd}'
Задача Blitz16. Напишите функцию fracdiv(a), которая принимает на вход строку вида “m/n”, где m и n – натуральные числа, и возвращает строку вида “m/n=p/q=x/z”, в которой записан процесс сокращения дроби “как в школе”, например, при вводе “24/64” функция должна вернуть строку “24/36=12/18=6/9=2/3”, а при входных данных “30/150” вывести “30/150=15/75=5/25=1/5”. В случае, если дробь несократима, вывести исходную дробь.
Решение Сивко Тимура Олеговича, ГУО "Гимназия №1 им. академика Ф.Е. Карского г. Гродно
from math import gcd
def l_cd(m, n):
for i in range(2, max(m, n)//2):
if m % i == 0 and n % i == 0:
return i
def fracdiv(a):
m, n = map(int, a.split('/'))
result = a
while m != 1 and n != 1 and gcd(m, n) != 1:
g = l_cd(m, n)
if g > 1:
m //= g
n //= g
result += '=' + str(m) + '/' + str(n)
return result
Задача Blitz17. Напишите программу, на вход которой подается натуральное число. Программа должна разместить десятичную точку между цифрами данного числа таким образом, чтобы произведение чисел, образованных слева и справа от точки было наибольшим. Например, для введенного числа 1234567 программа должна вывести 123456.7. Для числа 10101 программа должна вывести 10.101.
Авторское решение
z = int(input())
if z<100:
print ("%d.%d" % (z//10, z%10))
else:
z = str(z)
s = -1
for i in range(1, len(z)):
if s<(int(z[:i])*int(z[i:])):
s=int(z[:i])*int(z[i:])
ans = z[:i]+"."+z[i:]
print(ans)
Задача Blitz18. Напишите программу, которая принимает на вход строку, содержащую слова и дроби вида m/n, разделенные пробелами. Программа должна возвращать строку, в которой все дроби обернуты в скобки (m/n).
Решение Сивко Тимура Олеговича, ГУО "Гимназия №1 им. академика Ф.Е. Карского г. Гродно
import re
regex = re.compile(r"\d+\/\d+", re.MULTILINE)
print(regex.sub(lambda a: '(' + a.group() + ')', input()))
Задача Blitz19. Для передачи текстовых сообщений на русском языке в алфавите АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ разработан суперсекретный шифр. Шифр определяется кодовым словом, например БАНАН и цепочкой знаков +–++, которая содержит столько же символов “+” или “-“, сколько букв содержится в кодовом слове.
Разберем алгоритм шифрования на примере. Предположим, необходимо зашифровать слово ВЕЛОСИПЕД с ключом БАНАН и цепочкой +–++.
1. Кодовое слово определяет последовательность чисел 2, 1, 15, 1, 15 (буква Б имеет порядковый номер 2 в алфавите, буква А имеет порядковый номер 1, буква Н имеет порядковый номер 15 и т.д.), последовательность знаков +–++ показывает направление сдвига по алфавиту при шифровании.
2. Первая буква шифруемой фразы В шифруется сдвигом на 2 буквы вправо, то есть, буква В шифруется буквой Д.
Вторая буква шифруемой фразы Е определяется сдвигом на 1 букву влево, то есть Букве Е будет соответствовать Д.
Третья буква Л определяется сдвигом на 15 букв влево, то есть Р будет соответствовать буква Э (обратите внимание на цикличность сдвига, отсчет букв продолжается справа налево с последней буквы алфавита).
Четвертая буква О шифруется буквой П (сдвиг на 1 букву алфавита вправо).
Пятая буква С шифруется буквой А (сдвиг вправо на 15 букв алфавита с учетом цикличности).
И -> К
П -> О
Е -> Ц
Д -> Е
Таким образом ВЕЛОСИПЕД -> ДДЭПАКОЦЕ
3. Символ пробел ” ” при любом знаке “+” или “-” конвертируется в символ ” “.
Напишите программу, которая будет ДЕШИФРОВЫВАТЬ фразу в данном алфавите, если учесть, что разделитель слов в предложении – пробел, при шифровании остается пробелом.
На вход программы подается три строки через пробел, первая строка – кодовое слово, вторая строка – последовательность “+-“, третья строка – дешифруемое сообщение, например:
БАНАН +–++ ОДЩПЦРИГЛОБ ОСО
Результатом выполнения программы в данном случае будет строка
МЕЗОЗОЙСКАЯ ЭРА
Решение Сивко Тимура Олеговича, ГУО "Гимназия №1 им. академика Ф.Е. Карского г. Гродно
from itertools import cycle
alphabet = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'
alphabet_len = 33
code, signs, *words = input().split()
words = ' '.join(words)
code_signs = [-int(k + '1') * (alphabet.index(c) + 1) for c, k in zip(code, signs)]
iter = cycle(code_signs)
for b in words:
it = next(iter)
if b != ' ':
print(alphabet[(alphabet.index(b) + it) % alphabet_len], end='')
else:
print(' ', end='')
Задача Blitz20. Никому не известный математик Петр заметил, что некоторые числа обладают одним интересным свойством, например, число 80 может быть представлено как сумма чисел 67+6+7=80, число 106 как сумма чисел 89+8+9=109, число 1806=1320+1+320+13+20+132+0, число 42062=28936+2+8936+28+936+289+36+2893+6. Также Петр заметил, что далеко не все числа имеют такое свойство, например, для числа 11692 не существует ни одного такого “волшебного” числа, а некоторые числа имеют несколько чисел, из которых по этому правилу можно получить заданное число, например, для числа 729 существуют целых четыре волшебных числа:
729=630+6+30+63+0;
729=582+5+82+58+2;
729=627+6+27+62+7;
729=579+5+79+57+9.
Петр хочет осуществить свою давнишнюю мечту и сделать вклад в математическую науку, и он придумал функцию, которая по заданному числу определяет его “волшебность”, то есть количество чисел, суммы которых дают заданное число.
Напишите программу, которая по введенному числу определяет его “волшебность”.
Решить эту задачу полностью не удалось ни одному участнику, хотя были предложены решения, которые прошли по большинству тестов, но получили таймаут по значению 8423997, ответ, который должна выводить программа – 5.
Мы не приводим авторское решение задачи, но в качестве подсказки можем добавить, что уменьшить количество перебираемых вариантов можно, если подойти к решению задачи математически, и на каждом шаге рекурсии проверять не все возможные варианты, а решать системы уравнений, их количество будет существенно меньше.