ФГБОУ ВПО «БГПУ» им. М. Акмуллы
Центр развития одаренности школьников
ЗАДАНИЯ
2 тура дистанционной олимпиады по программированию
для 10-11 классов
г. Кумертау, Республика Башкортостан, МБОУ СОШ №12.
E-mail: *****@***com
Интерпретатор: Python 3.4.3
Исходники:
Yandex: https://yadi.sk/d/jBknbqginq6zf
Задание 1
Разработайте программу, которая формирует таблицу 10 на 10, заполняет ее случайными числами и сортирует по строкам.
Code:
# coding=utf-8
#!/usr/bin/python3
import random
arr = [sorted([str(random. randint(-1000, 1000)) for x in range(10)]) for k in range(10)]
# Список из 10 списков, заполненных случайными отсортированными числами от - 1000 до 1000
[print(', '.join(x)) for x in arr]
Out:
-211, -281, -303, -590, 343, 578, 749, 767, 963, 980
-369, -442, -553, 176, 433, 572, 6, 775, 896, 958
-149, -392, -525, -544, -551, -80, -973, 310, 368, 876
-368, -399, -772, -89, -890, 1, 126, 720, 830, 886
-632, -891, -95, 193, 303, 364, 412, 516, 858, 994
-286, -603, -773, -789, -95, 17, 450, 724, 786, 860
-583, -642, -691, 191, 239, 330, 357, 42, 425, 916
-275, -700, -94, 118, 295, 359, 38, 500, 509, 547
-159, -233, -503, -996, 240, 396, 475, 788, 854, 855
-27, -358, -383, -456, -707, -991, 26, 39, 592, 856
Screen:

Run:

Задание 2
Разработайте программу, которая формирует таблицу 10 на 10, заполняет ее случайными числами и сортирует по столбцам.
Code:
# coding=utf-8
# !/usr/bin/python3
import random
arr = [sorted([str(random. randint(-1000, 1000)) for x in range(10)]) for k in range(10)]
# Список из 10 списков, заролненных случайными отсортированными числами от - 1000 до 1000
[print(', '.join(x)) for x in list(reversed(list(zip(*arr))))]
# *a расспаковывает список, как аргумент функции zip, которая возвращает с n-ный элемент с каждого итерируемого в аргументах
Out:
829, 812, 993, 765, 996, 58, 318, 854, 342, 899
572, 537, 882, 606, 425, 464, 12, 760, -852, 896
53, 480, 790, 577, 383, 101, -841, 500, -831, 643
450, 19, 523, 280, 342, -987, -829, 434, -829, 275
434, 131, 518, -947, -794, -833, -817, 310, -77, -983
-829, -925, 376, -879, -676, -474, -540, -920, -699, -979
-682, -884, 317, -630, -649, -377, -462, -87, -695, -76
-461, -571, 293, -486, -524, -359, -297, -583, -556, -488
-358, -259, -536, -316, -4, -327, -249, -533, -407, -180
-103, -137, -405, -107, -196, -228, -239, -291, -113, -12
Screen:

Run:

Задание 3
Разработайте программу, которая формирует таблицу 10 на 10, заполняет ее случайными числами и находит наибольшие четные значения в каждом столбце.
Code:
# coding=utf-8
#!/usr/bin/python3
import random
a = [[str(random. randint(-1000, 1000)) for x in range(10)] for k in range(10)]
# Список из 10 списков, заролненных случайными числами от - 1000 до 1000
for i in a:
max_even = 'Нет четных'
for k in i:
k = int(k)
if k % 2 == 0 and k!= 0: # четное и не 0
if max_even == 'Нет четных':
max_even = k
else:
if max_even < k:
max_even = k
i. append('Максимальное четное: {}'.format(max_even))
[print(', '.join(x)) for x in a]
Out:
650, 216, 824, -273, 305, -634, -5, -541, 386, -329, Максимальное четное: 824
-516, -511, 139, -65, -463, -332, -364, -15, -173, 674, Максимальное четное: 674
-572, -228, 914, 15, 454, 368, 598, -77, -603, -708, Максимальное четное: 914
899, -59, 236, -101, -110, -267, -189, -875, -44, -192, Максимальное четное: 236
376, 129, 270, 183, 455, 217, -385, -316, -621, -908, Максимальное четное: 376
-339, -858, 200, -208, 970, -593, 272, 411, -463, 658, Максимальное четное: 970
110, -831, -184, -816, 922, -989, -988, -45, -703, 189, Максимальное четное: 922
170, 12, 862, -812, -764, -999, 811, -214, -25, -911, Максимальное четное: 862
-926, 11, -944, -758, 53, 980, -789, 980, -93, 755, Максимальное четное: 980
-375, -819, -497, 647, -176, 286, -465, 934, -260, -770, Максимальное четное: 934
Screen:

Run:

Задание 4
Разработайте программу для кодирования последовательности из N символов, которая использует неравномерный минимальный двоичный код, позволяющий однозначно декодировать полученную двоичную последовательность.
Code:
# coding=utf-8
# !/usr/bin/python3
import math
import sys
def generate(end):
"""
:param end: Генерировать двоичный код до 2**end
:return:список с возможными вариантами двоичного кода
"""
counter = 0
alpha = [['0', '1']]
while True:
if counter == end:
break
buf = []
for i in alpha[counter]:
buf. append(i + '0')
buf. append(i + '1')
alpha. append(buf)
counter += 1
return alpha[-1]
def make_primal_alpha(word):
"""
Составляет словарь с первичными НЕ минимальным "алфавитом"
"""
unique = set(word)
end = math. ceil(math. log2(len(unique))) - 1 # найти в какой радиус степени двойки попадают символы слова
alpha = generate(end)
result = {}
for letter, cipher in zip(unique, alpha):
result[letter] = cipher
return result
def test_seq(seq):
"""
Проверка последовательности на условаие Фано
"""
for i in range(len(seq)):
_seq = seq. copy()
_seq. pop(i)
for k in _seq:
if seq[i].startswith(k) or k == seq[i]:
return False
return True
def minimize(word):
"""
Составляет алфавит и минимизирует его для слов word
"""
unique = set(word)
primal_two = math. ceil(math. log2(len(unique))) - 1
alphabet = make_primal_alpha(word)
structured = [[x, word. count(x), alphabet[x]] for x in unique]
structured. sort(key=lambda x: x[1], reverse=True) # чтобы уменьшать сначало код букв, которых больше в слове
variables = [] # тут будут все возможные варианты уменьшения
for key, count, cipher in structured:
for z in range(primal_two): # чтобы еребрать все возможные варианты спускаясь вниз
reduced = alphabet. copy()
test = generate(primal_two - z)
for i in test:
reduced[key] = i
if test_seq(list(reduced. values())):
variables. append(reduced)
alphabet = reduced. copy() # чтобы дальше работать с уже уменьшеным кодом
break
minimum_alphabet = variables[-1] # последним элементом идет минимальный из возможных
cipher = ''.join([minimum_alphabet[x] for x in word])
return (word, cipher, minimum_alphabet)
for i in sys. stdin:
result = minimize(i. strip())
print('Слово: ', result[0])
print('Зашифрованное слово: ', result[1])
print('Алфавит: ', end='')
for i in result[2].items():
print(i[0], ':', i[1], end=' | ')
print('\n', '-'*30)
In:
приветпривет
she sells sea shells on the seashore
Карл у Клары украл кораллы, а Клара у Карла украла кларнет
word
test
vegetables
potato
*/+-дщдкек
Out:
Слово: приветпривет
Зашифрованное слово: 01011001001010110101100100101011
Алфавит: и : 00 | р : 11 | п : 010 | в : 100 | т : 011 | е : 101 |
------------------------------
Слово: she sells sea shells on the seashore
Зашифрованное слово: 1101111010001111010010011100011110101010001110111101001001110001100011000010000011110100011110101011101111000100101
Алфавит: t : 0000 | s : 11 | : 0001 | l : 001 | a : 0101 | r : 0100 | n : 0110 | e : 101 | o : 100 | h : 0111 |
------------------------------
Слово: Карл у Клары украл кораллы, а Клара у Карла украла кларнет
Зашифрованное слово: 01001110011001000000001000001000010111001101010000000110100111110010000010111000111110010001001011001000011100000100001011100111110000000100000100111001100101110000000110100111110010111000010100101110011100001110110
Алфавит: у : 0001 | л : 0010 | ы : 0101 | т : 0110 | е : 0111 | н : 1000 | а : 111 | , : 1001 | К : 0100 | р : 0011 | : 0000 | к : 101 | о : 110 |
------------------------------
Слово: word
Зашифрованное слово: 10000111
Алфавит: o : 00 | r : 01 | w : 10 | d : 11 |
------------------------------
Слово: test
Зашифрованное слово: 00011000
Алфавит: t : 00 | e : 01 | s : 10 |
------------------------------
Слово: vegetables
Зашифрованное слово: 101111011111000110010100111001
Алфавит: t : 000 | s : 001 | b : 010 | g
: 011 | v : 101 | e : 111 | a : 110 | l : 100 |
------------------------------
Слово: potato
Зашифрованное слово: 111000010010
Алфавит: t : 00 | a : 01 | o : 10 | p : 11 |
------------------------------
Слово: */+-дщдкек
Зашифрованное слово: 001011101100000110000111010111
Алфавит: д : 000 | * : 001 | е : 010 | / : 011 | - : 100 | + : 101 | щ : 110 | к : 111 |
------------------------------
Screen:

Run:
Задание 5
Разработайте программу, которая по четырехбайтовому IP-адресу узла и IP-адресу маски подсети вычисляет сетевой адрес.
Code:
# coding=utf-8
#!/usr/bin/python3
import sys
def generate(ip_or_mask):
"""
Заполняет нулями до 8 символов, переводя в двоичную систему
:param ip_or_mask: ip или маска
"""
ip_or_mask = [int(x) for x in ip_or_mask. split('.')]
res = []
for i in ip_or_mask:
st = '{0:b}'.format(i)
if len(st) < 8:
st = ('0' * (8 - len(st))) + st
res. append(st)
return res
def compare(ip_bin, netmask_bin):
"""
Поразрядно сравнивает двоичные значения ip и маски
:param ip_bin: ip в двоичной форме
:param netmask_bin: маска в двоичной форме
"""
result = []
for i, k in zip(ip_bin, netmask_bin):
temp = []
for x, y in zip(i, k):
x, y = int(x), int(y)
temp. append(str(x and y)) # по тому что bool(0) == False; bool(1) == True
result. append(temp)
return [''.join(x) for x in result]
def generate_subnet(ip, net_mask):
"""
Вычисляет сетевой адрес
"""
ip = generate(ip)
net_mask = generate(net_mask)
bin_subnet = compare(ip, net_mask)
subnet_result = '.'.join([str(eval('0b{}'.format(x))) for x in bin_subnet]) # выполняем строку в качестве кода
return subnet_result
input()
for i in sys. stdin:
tmp = i. split('\t\t')
ip = tmp[0]
mask = tmp[1]
print('IP: ', ip)
print('MASK: ', mask)
print('Сетевой адрес:', generate_subnet(ip, mask))
print('-'*30)
In:
IP MASK
192.168.192.168 255.254.6.4
165.250.120.99 254.64.128.216
265.250.230.209 254.44.158.216
16.25.100.89 16.74.128.216
185.283.121.14 51.64.86.190
Out:
IP: 192.168.192.168
MASK: 255.254.6.4
Сетевой адрес: 192.168.0.0
------------------------------
IP: 165.250.120.99
MASK: 254.64.128.216
Сетевой адрес: 164.64.0.64
------------------------------
IP: 265.250.230.209
MASK: 254.44.158.216
Сетевой адрес: 132.40.134.208
------------------------------
IP: 16.25.100.89
MASK: 16.74.128.216
Сетевой адрес: 16.8.0.88
------------------------------
IP: 185.283.121.14
MASK: 51.64.86.190
Сетевой адрес: 49.0.80.14
Screen: 
Run:

Задание 6
Разработайте программу для выдачи денег банкоматом по заданной клиентом сумме денег M кратной 50 рублям и наличию в банкомате X1 купюр по 50 рублей, X2 купюр по 100 рублей, X3 купюр по 1000 рублей, X4 купюр по 5000 рублей. Известно, что максимальная сумма для выдачи M не превышает 50000 рублей, минимальная сумма выдачи денег 50 рублей. После каждой выдачи денег, программа подсчитывает минимально возможные количества купюр X1, X2, X3, X4 и выдает сообщение "Банкомат временно не работает" в случае нехватки купюр для следующей выдачи денег по указанным условиям. Программа выполняет сначала учет ввода денег в банкомат для выдачи, а затем выдачу произвольных сумм клиентам банка.
Code:
# coding=utf-8
# !/usr/bin/python3
import random
import sys
class OutOfMoney(Exception): pass
def expand(bills, money):
_money = money
_bills = bills. copy()
pos_bills = [5000, 1000, 100, 50]
for i in pos_bills:
col = money // i
if col >= 1:
for k in range(col, 0, -1): # чтобы подобрать максимальное количество купуюр большего ноинала
if bills[i] - k >= 0 and money - k * i >= 0:
money -= k * i # вычитаем деньги которые можно выдать купюрами
bills[i] -= k
if money!= 0:
print('-' * 50)
print('Банкомат временно не работает')
raise OutOfMoney
print('Купюры: ', _bills)
print('Нужно снять: ', _money)
print('Осталось купюр: ', bills)
print('-' * 50)
return bills
bls = {j: random. randint(1, 100) for j in [5000, 1000, 100, 50]} # пусть изначальное кол-во купюр будет случайным
print('Купюры в банкомате: ', bls)
for i in sys. stdin:
try:
cash = int(i)
if cash < 50 or cash > 50000:
raise ValueError
except ValueError:
print('Неправильное Ввод ', i)
print('-' * 50)
continue
try:
bls = expand(bls, cash)
except OutOfMoney:
break
In:
7
500
50
6150
1650
6150
5000
1000
10000
45000
41250
42650
47850
950
50
150
47850
50000
700
600
Out:
Купюры в банкомате: {5000: 83, 1000: 41, 50: 98, 100: 51}
Неправильное Ввод 7
--------------------------------------------------
Купюры: {5000: 83, 1000: 41, 50: 98, 100: 51}
Нужно снять: 500
Осталось купюр: {5000: 83, 1000: 41, 50: 98, 100: 46}
--------------------------------------------------
Купюры: {5000: 83, 1000: 41, 50: 98, 100: 46}
Нужно снять: 50
Осталось купюр: {5000: 83, 1000: 41, 50: 97, 100: 46}
--------------------------------------------------
Купюры: {5000: 83, 1000: 41, 50: 97, 100: 46}
Нужно снять: 6150
Осталось купюр: {5000: 82, 1000: 40, 50: 96, 100: 45}
--------------------------------------------------
Купюры: {5000: 82, 1000: 40, 50: 96, 100: 45}
Нужно снять: 1650
Осталось купюр: {5000: 82, 1000: 39, 50: 95, 100: 39}
--------------------------------------------------
Купюры: {5000: 82, 1000: 39, 50: 95, 100: 39}
Нужно снять: 6150
Осталось купюр: {5000: 81, 1000: 38, 50: 94, 100: 38}
--------------------------------------------------
Купюры: {5000: 81, 1000: 38, 50: 94, 100: 38}
Нужно снять: 5000
Осталось купюр: {5000: 80, 1000: 38, 50: 94, 100: 38}
--------------------------------------------------
Купюры: {5000: 80, 1000: 38, 50: 94, 100: 38}
Нужно снять: 1000
Осталось купюр: {5000: 80, 1000: 37, 50: 94, 100: 38}
--------------------------------------------------
Купюры: {5000: 80, 1000: 37, 50: 94, 100: 38}
Нужно снять: 10000
Осталось купюр: {5000: 78, 1000: 37, 50: 94, 100: 38}
--------------------------------------------------
Купюры: {5000: 78, 1000: 37, 50: 94, 100: 38}
Нужно снять: 45000
Осталось купюр: {5000: 69, 1000: 37, 50: 94, 100: 38}
--------------------------------------------------
Купюры: {5000: 69, 1000: 37, 50: 94, 100: 38}
Нужно снять: 41250
Осталось купюр: {5000: 61, 1000: 36, 50: 93, 100: 36}
--------------------------------------------------
Купюры: {5000: 61, 1000: 36, 50: 93, 100: 36}
Нужно снять: 42650
Осталось купюр: {5000: 53, 1000: 34, 50: 92, 100: 30}
--------------------------------------------------
Купюры: {5000: 53, 1000: 34, 50: 92, 100: 30}
Нужно снять: 47850
Осталось купюр: {5000: 44, 1000: 32, 50: 91, 100: 22}
--------------------------------------------------
Купюры: {5000: 44, 1000: 32, 50: 91, 100: 22}
Нужно снять: 950
Осталось купюр: {5000: 44, 1000: 32, 50: 90, 100: 13}
--------------------------------------------------
Купюры: {5000: 44, 1000: 32, 50: 90, 100: 13}
Нужно снять: 50
Осталось купюр: {5000: 44, 1000: 32, 50: 89, 100: 13}
--------------------------------------------------
Купюры: {5000: 44, 1000: 32, 50: 89, 100: 13}
Нужно снять: 150
Осталось купюр: {5000: 44, 1000: 32, 50: 88, 100: 12}
--------------------------------------------------
Купюры: {5000: 44, 1000: 32, 50: 88, 100: 12}
Нужно снять: 47850
Осталось купюр: {5000: 35, 1000: 30, 50: 87, 100: 4}
--------------------------------------------------
Купюры: {5000: 35, 1000: 30, 50: 87, 100: 4}
Нужно снять: 50000
Осталось купюр: {5000: 25, 1000: 30, 50: 87, 100: 4}
--------------------------------------------------
Купюры: {5000: 25, 1000: 30, 50: 87, 100: 4}
Нужно снять: 700
Осталось купюр: {5000: 25, 1000: 30, 50: 81, 100: 0}
--------------------------------------------------
Купюры: {5000: 25, 1000: 30, 50: 81, 100: 0}
Нужно снять: 600
Осталось купюр: {5000: 25, 1000: 30, 50: 69, 100: 0}
Screen:
Run:
Задание 7
Представим себе бесконечную последовательность цифр, составленную из записанных друг за другом возрастающих степеней десятки. Вот начало этой последовательности: 110100100010000… Всё, что надо — определить, какая цифра находится в такой последовательности на определённом месте.
Исходные данные
В первой строке находится целое число N (1 ≤ N ≤ 65535). В i-й из N последующих строк записано целое число Ki — номер позиции в последовательности (1 ≤ Ki ≤ 231 − 1).
Результат
Выведите через пробел N цифр. i-я цифра должна равняться цифре, которая находится в описанной выше последовательности на позиции с номером Ki.
Пример
исходные данные | результат |
4 3 14 7 6 | 0 0 1 0 |
Code:
#!/usr/bin/python3
# coding=utf-8
import sys
def make_lazy_seq(k_max):
"""
Позиция каждой n-ной единички вычисляется по формуле (n*(n+1)) * 1/2 + 1
Эта функция генерирует список положений единички до k_max
"""
def infinity_generator():
i = 0
while True:
yield i
i += 1
lazy_caterers_sequence = []
for n in infinity_generator():
x = (0.5 * n * (n + 1)) + 1
lazy_caterers_sequence. append(x)
if x > k_max:
break
return lazy_caterers_sequence
seq = make_lazy_seq(2 ** 31 - 1)
for i in sys. stdin:
try:
position = int(i)
if position < 0 or position > 2 ** 31 - 1:
raise ValueError
except ValueError:
print('Неправильное число')
continue
if position in seq:
print('1', end=' ')
else:
print('0', end=' ')
print()
In:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
14
7
6
16
21
22
23
65535
5424
34
64
35
78
98
Out:
1 1 0 1 0 0 1 0 0 0 1 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0
Screen:
Run:

Задание 8
Условие этой задачи очень простое: вам всего лишь надо определить, сколько клеток находится под боем шахматного коня, одиноко стоящего на шахматной доске. На всякий случай напомним, что конь ходит буквой «Г» — на две клетки по горизонтали или вертикали в любом направлении, и потом на одну клетку в направлении, перпендикулярном первоначальному.
Исходные данные
В первой строке находится единственное число N, 1 ≤ N ≤ 100 — количество тестов. В каждой из последующих Nстрок содержится очередной тест: два символа (маленькая латинская буква от 'a' до 'h' и цифра от 1 до 8) — стандартное шахматное обозначение клетки, на которой стоит конь. При этом буква обозначает вертикаль, а цифра — горизонталь.
Результат
Выведите N строк: в каждой из них должно находиться единственное число — количество клеток шахматной доски, находящихся под боем коня.
Пример
исходные данные | результат |
3 a1 d4 g6 | 2 8 6 |
Code:
# coding=utf-8
#!/usr/bin/python3
import string
def killer_horse(horse):
board = [[0 for x in range(8)] for k in range(8)] # составляем пустую доску
numerated_alphabet = {i:j for i, j in zip(string. ascii_lowercase, range(len(string. ascii_lowercase)))} # нумеруем английский алфавит
horse = (int(numerated_alphabet[horse[0]]), int(horse[1]) - 1) # заменяем букву на её положение в алфавите, чтобы получить координату
# (ver, hor)
turns = [(2, -1), (2, 1), (-1, -2), (1, -2), (-2, -1), (-2, 1), (-1, 2), (1, 2)] # Возможные ходы коня в разные стороны
possible_turns = 0
for i in turns:
go = horse[0] + i[0], horse[1] + i[1] # Пробует сходить
if False not in [x in range(0, 7) for x in go]: # из за индексов в python тк. индекс от отр. числа будет брать элементы с конца
try:
board[go[0]][go[1]]
except IndexError:
pass
else:
possible_turns += 1 # если небыло исключения
return possible_turns
input()
while True:
try:
cell = input()
except EOFError:
break
print(killer_horse(cell))
In:
10
a1
d4
g6
f8
a4
c3
c6
h1
f4
e2
Out:
2
8
6
4
4
8
8
2
8
6
Screen:
Run:


