- 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 баллов при условии, что и основное решение и дополнительное успешно прошли все тесты. Дополнительное решение должно существенно отличается по методу решения задачи. Сделали это для подстраховки, если будут ученики, решившие все задачи и набравшие максимальные баллы. Спойлер - такого не случилось. Отчасти потому что задачи были составлены не одного уровня, а от совсем простых до очень-очень сложных.

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

Разборы решений, ниже под спойлерами сами задачи и код на python

Задача 1

Через ввод с клавиатуры задаётся количество чисел. Затем сами числа передаются через ввод пользователя с клавиатуры и заносятся в готовый пустой список. Составить программу, подсчитывающую среднее арифметическое. Результат записывается в переменную. Визуально(scratch/snap) – на экране отображается результат любым способом (например, функция говорить/думать). Текстовое (python) – результат выводится в консоль на экран.

Примерный тест:

Входные данные:

Выходные данные:

5

1 2 3 4 5

 3

Решение 1
a = int(input("Количество чисел:"))
y = 0
for i in range(a):
    x = float(input("Число:"))
    y += x
y = y / a
print("Среднее арифметическое: " + str(y))

Задача 2

У Кота, Пса и Птицы имеется по некоторому количеству грибов (у всех по разному количеству).  Данные по количеству передаются через ввод пользователя с клавиатуры и заносятся в готовый пустой список, где первый элемент - грибы Кота, второй элемент -  грибы Пса, третий элемент - грибы Птицы.

Составить программу, определяющую, у кого из них наибольшее количество. Результат записывается в переменную. Визуально (scratch/snap) – на экране появляется персонаж с наибольшим количеством грибов и говорит (функция говорить/думать)) количество грибов. Текстовое (python) – имя персонажа выводится в консоль на экран.

Примерный тест:

Входные данные

10 30 20

20 10 30

Выходные данные

Пёс

Птица

Решение 2
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("Птица")

Задача 3

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

Составить программу для определения у кого сколько осталось яблок. Результат записывается в список. Визуально (scratch/snap) – на экране отображаются пять девочек (обязательно использование клонов) и говорят (функция говорить/думать) количество яблок. Текстовое (python) – количество яблок выводятся в консоль на экран. По каждой девочке? По порядку отдельной строкой.

Примерный тест:

Входные данные:

Выходные данные:

5

10 20 30 40 50

 9

18

27

36

45

Решение 3
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])

Задача 4

День недели задаётся через ввод пользователя с клавиатуры числом от 1 до 7. Составить программу, в которой визуально (scratch/snap) – на экране отображается название этого дня любым способом (например, функция говорить/думать). Текстовое (python) – название дня выводится в консоль на экран.

Примерный тест:

Входные данные

1

3

Выходные данные

Понедельник

Среда

Решение 4
days = ['Понедельник','Вторник','Среда','Четверг','Пятница','Суббота','Воскресенье']
day = int(input())
print(days[day - 1])

Задача 5

Через ввод с клавиатуры задаётся количество чисел. Затем сами числа передаются через ввод пользователя с клавиатуры и заносятся в готовый пустой список. Сделать программу, изменяющую элементы списка, числа кратные 5 заменять на 2 (умноженную на кратность заменяемого числа), а числа кратные 2 заменять на 5 (умноженную на кратность заменяемого числа). Числа передаются в готовый пустой список. Результат записывается в список. Визуально (scratch/snap) – на экране отображаются все элементы списка любым способом (например, функция говорить/думать). Текстовое (python) – элементы списка выводится в консоль на экран в одну строку.

Примерный тест:

Входные данные:

Выходные данные:

6

10 2 6 20 4 5

4 5 15 8 10 2

Решение 5
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])

Задача 6

Условие этой задачи очень простое: вам всего лишь надо определить, сколько клеток находится под боем шахматного коня, одиноко стоящего на шахматной доске. На всякий случай напомним, что конь ходит буквой «Г» — на две клетки по горизонтали или вертикали в любом направлении, и потом на одну клетку в направлении, перпендикулярном первоначальному. Программа получает на вход через вводы пользователя с клавиатуры два числа от 1 до 8 каждое, задающие номер столбца и номер строки, обозначающие позицию коня на шахматной доске. Визуально (scratch/snap) – на экране отображаются любым способом (например, функция говорить/думать) количество клеток шахматной доски, находящихся под боем коня. Текстовое (python) – количество клеток шахматной доски, находящихся под боем коня выводится в консоль на экран.

Примерный тест:

Входные данные:

Выходные данные:

1 5

4

8 1

2

Решение 6
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)

Задача 7

Заданы две клетки шахматной доски. Если они покрашены в один цвет, то выведите слово YES, а если в разные цвета — то NO. Программа получает на вход через вводы пользователя с клавиатуры четыре числа от 1 до 8 каждое, задающие номер столбца и номер строки сначала для первой клетки, потом для второй клетки. Визуально (scratch/snap) – на экране отображаются любым способом (например, функция говорить/думать) YES или NO. Текстовое (python) – выведите YES или NO в консоль на экран.

Примерный тест:

Входные данные:

Выходные данные:

1 1 2 6

YES

Решение 7
summ = 0
for i in range(4):
    summ += int(input())
if summ % 2 ==0:
    print('YES')
else:
    print('NO')

Задача 8

На ипподроме наметилось городское соревнование. Но никто не знает сколько будет участников. Места всем хватит, но есть проблема с расширением стартового загона. Представьте загон в виде квадратной таблицы. Участника номер один необходимо ставить в правом верхнем (переднем) углу, далее участников ставят по диагоналям сверху вниз, последний участник стоит в левом нижнем углу. Чтобы быстро сделать расстановку необходимо вывести на табло данную таблицу. Организатор в последний момент сообщит Вам только количество участников (программа получает на вход через ввод пользователя с клавиатуры одно число).

Визуально (scratch/snap) – на экране рисуется таблица, в каждой ячейке вместо обычных чисел используйте точки, какое число – столько сгруппированных точек в ячейке. Текстовое (python) – вывести в консоль на экран таблицу с числовой расстановкой.

Примерный тест:

Входные данные:

Выходные данные текстовое:

9

4 2 1

7 5 3

9 8 6

Решение 8
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()

Задача 9

В наш город приехал чудо-зоопарк с множеством зверей. Одних только пингвинов 3 вида, 4 вида черепах, 5 видов акул и т.д. Вы весь день записывали названия животных в блокнот, а вечером решили подсчитать каких животных (не разделяя на виды) было больше всего. Сколько в блокноте всего животных неизвестно, но точно понятно, что каких-то животных больше и что сначала записано животное, а затем его вид, например, «Penguin Emperor». В каждой из следующих строк блокнота записано по одному виду животного. На вход подаётся файл input.txt с данными. Для scratch/snap в программе необходим пустой список для ручного импорта в него файла. Визуально (scratch/snap) – на экране отображаются любым способом (например, функция говорить/думать) название животного и их количество. Текстовое (python) – в консоль на экран в одну строку выводится название животного и их количество.

Примерный тест:

Входные данные:

Выходные данные:

Penguin Emperor

Shark zebra

Turtle Caiman

Shark white

Shark 2

Решение 9
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=" ")

Задача 10

Поговаривают, что сейчас самая популярная игра у школьников - 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

Решение 10
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