- PVSM.RU - https://www.pvsm.ru -
В этой статье я расскажу про опыт проведения городской школьной олимпиады по программированию.
Идея организовать местную олимпиаду возникла ещё на стадии запуска детской школы программирования [1]. За два года работы стало ещё более очевидно, что счёт идёт на единицы различных соревнований в этом направлении, а значит мало возможностей для проверки учеников, вовлечения вне занятий, дополнительной мотивации результатами. Скажу даже так: в Иркутске нет соревновательных мероприятий для учеников по программированию на scratch, и только одна олимпиада в которой могут участвовать питонисты - “Играем в программистов”.
Казалось, что организовать олимпиаду нужно много ресурсов: найти большое помещение, например договориться с крупной библиотекой, обеспечить техникой, найти преподавателей-волонтёров, обеспечить безопасность и море других мелочей. И это было некоторым камнем преткновения для частного небольшого учебного заведения в части ресурсов. Решение пришло неожиданно - дистанционная олимпиада! В феврале 2020 года пошли слухи про скорую удалёнку, что очные мероприятия запретят и для меня всё стало на свои места.
Теперь про организацию олимпиады:
Задания мы выложили в вконтакте в своей группе 20 марта 2020 года. Время для решения задач дали чуть больше недели - с 20 марта 2020 года по 29 марта 2020 года. Оценку работ планировали провести до 12 апреля 2020 года, даже сомневались не мало ли, но справились всего за 4 дня. При этом участников было чуть больше 100, проверка была ручная(но об этом попозже).
Участников поделили на три категории:
младшая ступень (до 7 класса общеобразовательных учреждений включительно, задачи решены на визуальном языке программирования scratch/snap)
средняя ступень (до 7 класса общеобразовательных учреждений включительно, задачи решены на любом разрешённом олимпиадой языке программирования)
старшая ступень (8-11 классы общеобразовательных учреждений, задачи решены на любом разрешённом олимпиадой языке программирования).
Что же это за такие разрешённые языки. Мы посоветовались с муниципальными коллегами, которые проводят уже больше 15 лет олимпиаду “Играем в программистов” и допустили следующий список:
Язык |
Редактор |
Компилятор |
C++ |
Code: Blocks, VisualStudio |
VisualStudio 2019 |
C# |
Code: VisualStudio |
VisualStudio 2019 |
Pascal |
FreePascal 2.6.2 |
FreePascal 2.6.2 |
Basic |
FreeBasic 0.90.1 |
FreeBasic 0.90.1 |
Java |
NetBeans, Eclipse |
JDK 1.7.0 |
Python |
IDLE |
Python 3.6 |
Учащимся предлагались задания с указанием максимального количества баллов за каждую задачу и примерными тестами к ней. Решения заданий олимпиады должны были предоставить в виде исходного кода на языке программирования. Ничего необычного. Главное - обозначить как правильно называть имена файлов, по опыту преподавания - дети любят творческие названия проектов. Мы прописали в положении к олимпиаде такое правило: Имя файла даётся по следующему принципу: до 5 символов – название учебного заведения с указанием территории, 2 символа – инициалы участника и последний символ – номер задачи. В имени файла можно использовать только латинские буквы и цифры, первый символ – буква. В основном все следовали указаниям. Когда проверяешь сотни работ, у каждого одни задачи решены, другие нет - соблюдение данного пункта очень экономит время на проверке.
На каждую задачу делали по 5 тестов, за каждый пройденный тест начисляли по 2 балла. Разрешили предоставление дополнительных решений задач. За каждое дополнительное решение начисляли 5 баллов при условии, что и основное решение и дополнительное успешно прошли все тесты. Дополнительное решение должно существенно отличается по методу решения задачи. Сделали это для подстраховки, если будут ученики, решившие все задачи и набравшие максимальные баллы. Спойлер - такого не случилось. Отчасти потому что задачи были составлены не одного уровня, а от совсем простых до очень-очень сложных.
Теперь приведём сами задачки и наши варианты решений, которые мы публиковали для учеников своей школы в рамках их образовательной программы вместе с разбором решений.
Через ввод с клавиатуры задаётся количество чисел. Затем сами числа передаются через ввод пользователя с клавиатуры и заносятся в готовый пустой список. Составить программу, подсчитывающую среднее арифметическое. Результат записывается в переменную. Визуально(scratch/snap) – на экране отображается результат любым способом (например, функция говорить/думать). Текстовое (python) – результат выводится в консоль на экран.
Примерный тест:
Входные данные: |
Выходные данные: |
5 1 2 3 4 5 |
3 |
a = int(input("Количество чисел:"))
y = 0
for i in range(a):
x = float(input("Число:"))
y += x
y = y / a
print("Среднее арифметическое: " + str(y))
У Кота, Пса и Птицы имеется по некоторому количеству грибов (у всех по разному количеству). Данные по количеству передаются через ввод пользователя с клавиатуры и заносятся в готовый пустой список, где первый элемент - грибы Кота, второй элемент - грибы Пса, третий элемент - грибы Птицы.
Составить программу, определяющую, у кого из них наибольшее количество. Результат записывается в переменную. Визуально (scratch/snap) – на экране появляется персонаж с наибольшим количеством грибов и говорит (функция говорить/думать)) количество грибов. Текстовое (python) – имя персонажа выводится в консоль на экран.
Примерный тест:
Входные данные |
10 30 20 |
20 10 30 |
Выходные данные |
Пёс |
Птица |
s = []
for i in range(3):
griby = int(input())
s.append(griby)
if s[0]>s[1] and s[0]>s[2]:
print("Кот")
elif s[1]>s[2]:
print("Пёс")
else:
print("Птица")
Через ввод с клавиатуры задаётся количество девочек, у которых было по некоторому количеству яблок. Данные по количеству передаются в готовый пустой список. Каждая девочка съела по стольку яблок, каков её порядковый номер.
Составить программу для определения у кого сколько осталось яблок. Результат записывается в список. Визуально (scratch/snap) – на экране отображаются пять девочек (обязательно использование клонов) и говорят (функция говорить/думать) количество яблок. Текстовое (python) – количество яблок выводятся в консоль на экран. По каждой девочке? По порядку отдельной строкой.
Примерный тест:
Входные данные: |
Выходные данные: |
5 10 20 30 40 50 |
9 18 27 36 45 |
girls = int(input())
apple = []
for numgirl in range(1, girls + 1):
a = int(input())
a = a - numgirl
apple.append(a)
for numgirl in range(girls):
print(apple[numgirl])
День недели задаётся через ввод пользователя с клавиатуры числом от 1 до 7. Составить программу, в которой визуально (scratch/snap) – на экране отображается название этого дня любым способом (например, функция говорить/думать). Текстовое (python) – название дня выводится в консоль на экран.
Примерный тест:
Входные данные |
1 |
3 |
Выходные данные |
Понедельник |
Среда |
days = ['Понедельник','Вторник','Среда','Четверг','Пятница','Суббота','Воскресенье']
day = int(input())
print(days[day - 1])
Через ввод с клавиатуры задаётся количество чисел. Затем сами числа передаются через ввод пользователя с клавиатуры и заносятся в готовый пустой список. Сделать программу, изменяющую элементы списка, числа кратные 5 заменять на 2 (умноженную на кратность заменяемого числа), а числа кратные 2 заменять на 5 (умноженную на кратность заменяемого числа). Числа передаются в готовый пустой список. Результат записывается в список. Визуально (scratch/snap) – на экране отображаются все элементы списка любым способом (например, функция говорить/думать). Текстовое (python) – элементы списка выводится в консоль на экран в одну строку.
Примерный тест:
Входные данные: |
Выходные данные: |
6 10 2 6 20 4 5 |
4 5 15 8 10 2 |
nums = int(input())
listnums = []
for i in range(nums):
listnums.append(int(input()))
for i in range(nums):
if listnums[i] % 5 == 0:
listnums[i] = listnums[i] // 5 * 2
elif listnums[i] % 2 == 0:
listnums[i] = listnums[i] // 2 * 5
print(listnums[i])
Условие этой задачи очень простое: вам всего лишь надо определить, сколько клеток находится под боем шахматного коня, одиноко стоящего на шахматной доске. На всякий случай напомним, что конь ходит буквой «Г» — на две клетки по горизонтали или вертикали в любом направлении, и потом на одну клетку в направлении, перпендикулярном первоначальному. Программа получает на вход через вводы пользователя с клавиатуры два числа от 1 до 8 каждое, задающие номер столбца и номер строки, обозначающие позицию коня на шахматной доске. Визуально (scratch/snap) – на экране отображаются любым способом (например, функция говорить/думать) количество клеток шахматной доски, находящихся под боем коня. Текстовое (python) – количество клеток шахматной доски, находящихся под боем коня выводится в консоль на экран.
Примерный тест:
Входные данные: |
Выходные данные: |
1 5 |
4 |
8 1 |
2 |
vozmojnost = 0
stolb = int(input())
stroka = int(input())
# Конь ходит вправо
if stolb + 2 < 9:
if stroka + 1 < 9: # и вверх
vozmojnost += 1
if stroka - 1 > 0: # и вниз
vozmojnost += 1
# Конь ходит влево
if stolb - 2 > 0:
if stroka + 1 < 9: # и вверх
vozmojnost += 1
if stroka - 1 > 0: # и вниз
vozmojnost += 1
# Конь ходит вверх
if stroka + 2 < 9:
if stolb + 1 < 9: # и вправо
vozmojnost += 1
if stolb - 1 > 0:# и влево
vozmojnost += 1
# Конь ходит вниз
if stroka - 2 > 0:
if stolb + 1 < 9:# и вправо
vozmojnost += 1
if stolb - 1 > 0:# и влево
vozmojnost += 1
print(vozmojnost)
Заданы две клетки шахматной доски. Если они покрашены в один цвет, то выведите слово YES, а если в разные цвета — то NO. Программа получает на вход через вводы пользователя с клавиатуры четыре числа от 1 до 8 каждое, задающие номер столбца и номер строки сначала для первой клетки, потом для второй клетки. Визуально (scratch/snap) – на экране отображаются любым способом (например, функция говорить/думать) YES или NO. Текстовое (python) – выведите YES или NO в консоль на экран.
Примерный тест:
Входные данные: |
Выходные данные: |
1 1 2 6 |
YES |
summ = 0
for i in range(4):
summ += int(input())
if summ % 2 ==0:
print('YES')
else:
print('NO')
На ипподроме наметилось городское соревнование. Но никто не знает сколько будет участников. Места всем хватит, но есть проблема с расширением стартового загона. Представьте загон в виде квадратной таблицы. Участника номер один необходимо ставить в правом верхнем (переднем) углу, далее участников ставят по диагоналям сверху вниз, последний участник стоит в левом нижнем углу. Чтобы быстро сделать расстановку необходимо вывести на табло данную таблицу. Организатор в последний момент сообщит Вам только количество участников (программа получает на вход через ввод пользователя с клавиатуры одно число).
Визуально (scratch/snap) – на экране рисуется таблица, в каждой ячейке вместо обычных чисел используйте точки, какое число – столько сгруппированных точек в ячейке. Текстовое (python) – вывести в консоль на экран таблицу с числовой расстановкой.
Примерный тест:
Входные данные: |
Выходные данные текстовое: |
9 |
4 2 1 7 5 3 9 8 6 |
vvod = int(input())
num = vvod ** 0.5
if int(num) != num:
num = int(num) + 1
else:
num = int(num)
table = [[0] * num for i in range(num)]
numb = 0
ivert = num
for i in range(num):
if ivert > 0:
igoriz = 0
for i in range(num - ivert + 1):
if igoriz <= num - ivert:
numb += 1
if numb <= vvod:
table[igoriz][ivert + igoriz - 1] = numb
else:
table[igoriz][ivert + igoriz - 1] = 0
igoriz += 1
ivert -= 1
ivert = 1
for i in range(num - 1):
if ivert < num:
igoriz = 0
for i in range(num - ivert):
if igoriz < num - ivert:
numb += 1
if numb <= vvod:
table[ivert + igoriz][igoriz] = numb
else:
table[ivert + igoriz][igoriz] = 0
igoriz += 1
ivert += 1
for row in table:
for elem in row:
print(elem, end=' ')
print()
В наш город приехал чудо-зоопарк с множеством зверей. Одних только пингвинов 3 вида, 4 вида черепах, 5 видов акул и т.д. Вы весь день записывали названия животных в блокнот, а вечером решили подсчитать каких животных (не разделяя на виды) было больше всего. Сколько в блокноте всего животных неизвестно, но точно понятно, что каких-то животных больше и что сначала записано животное, а затем его вид, например, «Penguin Emperor». В каждой из следующих строк блокнота записано по одному виду животного. На вход подаётся файл input.txt с данными. Для scratch/snap в программе необходим пустой список для ручного импорта в него файла. Визуально (scratch/snap) – на экране отображаются любым способом (например, функция говорить/думать) название животного и их количество. Текстовое (python) – в консоль на экран в одну строку выводится название животного и их количество.
Примерный тест:
Входные данные: |
Выходные данные: |
Penguin Emperor Shark zebra Turtle Caiman Shark white |
Shark 2 |
file = open("input.txt")
animal=[]
kolvo=[]
for stroka in file:
data = stroka.split()
animal.append(data[0])
for i in animal:
kolvo.append(animal.count(i))
maxi = 0
pos = 0
for i in range(len(kolvo)):
if kolvo[i] > maxi:
maxi = kolvo[i]
pos = i
print(animal[i], maxi, end=" ")
Поговаривают, что сейчас самая популярная игра у школьников - brawl stars. Ты наверняка чемпион и прокачал множество персонажей. Близится соревнование и поэтому надо разбить персонажей на две равные команды. У вас есть несколько персонажей известного уровня w1, …, wn. Напишите программу, которая распределит персонажей в две команды так, что разность суммы уровней этих двух команд будет минимальной. Ввод содержит уровни персонажей w1, …, wn (1 ≤ wi ≤ 100) через пробел с именами персонажей. На вход подаётся файл input.txt с данными. Для scratch/snap в программе необходим пустой список для ручного импорта в него файла
Ваша программа должна вывести имена персонажей первой команды, затем одно число — минимальную разность уровней двух команд. Затем имена персонажей второй команды.
Визуально (scratch/snap) – вывод последовательно заносится в список. Текстовое (python) – ответ выводится в консоль на экран отдельными строками.
Примерный тест:
Входные данные: |
Выходные данные |
4 Shelly 7 Bull 10 Bo 12 8-bit 15 ElPrimo 20 Tick |
Tick Bo Shelly 0 ElPrimo 8-bit Bull |
file = open("input.txt")
pers_dict = []
for pers in file:
data = pers.split()
pers_dict.append((data[1], int(data[0])))
pers_dict.sort(key = lambda elem: elem[1], reverse = True)
command1 = []
command2 = []
summa1=0
summa2=0
for elem in pers_dict:
if summa1 <= summa2:
command1.append(elem)
summa1 += elem[1]
else:
command2.append(elem)
summa2 += elem[1]
for key in command1:
print(key[0])
if summa1> summa2:
print(summa1-summa2)
else:
print(summa2-summa1)
for key in command2:
print(key[0])
Какими выводами хотелось бы поделиться по итогам:
Организовать городскую олимпиаду просто, сделайте её дистанционной, не переживайте за гугление участниками, разработайте свои задачи и тогда нагуглить решение будет в разы сложнее, чем решить.
Финансирование олимпиады - дело минимальное, берите пример с Роббо, они Российскую олимпиаду по scratch проводят мега бюджетно - электронные дипломы и сертификаты участника с факсимиле организатора, но сути это не меняет - красивая электронная "бумажка" в наличии.
Не нужно придумывать автоматизированную проверку, не так страшно ручное тестирование решений. Главное заранее подготовьте тесты.
Думаете будет мало участников? Разошлите электронные письма в школы города. Всегда найдётся педагоги, которые очень заинтересованы в таких мероприятиях.
Наша олимпиада оказалась очень сложной для школьников всех возрастов, хотя я переживал об обратном. Реально полезной оказалась градация задач по сложности. Задачи 8-10 можно смело забыть, вместо них мы решили в будущем добавить 6 простых задач, схожих по уровню с 4 задачей.
Я очень надеюсь, что статья будет полезной руководителям кружков программирования и педагогам. Смело проводите местные олимпиады, смотрите решения ваших учеников, делайте выводы для улучшения своей образовательной программы.
Автор: Евгений Бутырин
Источник [2]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/357119
Ссылки в тексте:
[1] детской школы программирования: https://www.instagram.com/masterkoda38/
[2] Источник: https://habr.com/ru/post/519836/?utm_source=habrahabr&utm_medium=rss&utm_campaign=519836
Нажмите здесь для печати.