Редакция для Сигнал от тестовой группы
Submitting an official solution before solving the problem yourself is a bannable offence.
Автор:
Разбор задачи «Сигнал от тестовой группы»
Идея задачи
Нам дано n оценок, каждая из которых равна либо 0, либо 1:
0— тестировщик считает задачу простой;1— тестировщик считает задачу сложной.
Нужно определить итоговый вердикт:
- если хотя бы одна оценка равна
1, выводимHARD; - если все оценки равны
0, выводимEASY.
По сути, задача сводится к очень простой проверке: есть ли в массиве хотя бы одна единица.
Наблюдение
Нам не нужно ничего подсчитывать подробно.
Как только мы встретили число 1, ответ уже однозначно известен — это HARD.
Если же после просмотра всех чисел единица так и не встретилась, значит все элементы равны 0, и ответ — EASY.
Это позволяет решить задачу за один проход по входным данным.
Пошаговый алгоритм
- Считываем число
n. - Последовательно считываем
nчисел. - Если среди них встретилось число
1, сразу выводимHARDи завершаем программу. - Если цикл закончился и ни одной единицы не было, выводим
EASY.
Почему это правильно
Докажем корректность решения.
Рассмотрим два возможных случая.
Случай 1. Среди оценок есть хотя бы одна 1
По условию, если хотя бы один тестировщик считает задачу сложной, итоговый ответ должен быть HARD.
Наш алгоритм при первом же обнаружении 1 выводит HARD. Значит, в этом случае он работает правильно.
Случай 2. Среди оценок нет ни одной 1
Так как каждая оценка может быть только 0 или 1, отсутствие единиц означает, что все оценки равны 0.
По условию в таком случае ответ должен быть EASY.
Наш алгоритм именно это и выводит после завершения цикла. Значит, и во втором случае решение корректно.
Следовательно, алгоритм всегда выводит правильный ответ.
Оценка сложности
Мы просматриваем каждый элемент не более одного раза.
- Время:
O(n) - Память:
O(1)
Это оптимальное решение для данной задачи.
Реализация на C++
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
if (x == 1) {
cout << "HARD\n";
return 0;
}
}
cout << "EASY\n";
return 0;
}
Комментарий к коду
Мы не храним все числа в массиве, потому что это не нужно.
Каждое число можно обработать сразу после чтения:
- встретили
1— сразу печатаемHARD; - если до конца входа единица не встретилась — печатаем
EASY.
Такой подход делает решение не только простым, но и аккуратным.
Реализация на Python
n = int(input())
a = list(map(int, input().split()))
for x in a:
if x == 1:
print("HARD")
break
else:
print("EASY")
Комментарий к коду
Здесь используется конструкция for ... else.
Она работает так:
- если внутри цикла сработал
break, блокelseне выполняется; - если цикл завершился естественно, блок
elseвыполнится.
Значит:
- если нашли
1, печатаемHARDи выходим из цикла; - если не нашли ни одной
1, после завершения цикла печатаемEASY.
Более простой вариант на Python
Можно записать решение ещё короче:
n = int(input())
a = list(map(int, input().split()))
if 1 in a:
print("HARD")
else:
print("EASY")
Этот вариант тоже полностью корректен.
Частые ошибки
1. Лишний подсчёт количества единиц
Некоторые пытаются считать, сколько раз встретилась 1. Это не ошибка, но это избыточно.
Для ответа важно только одно: есть единица или нет.
2. Неправильное сравнение
Иногда по невнимательности пишут проверку только для первого элемента или только для последнего. Нужно просмотреть все оценки, пока не встретится 1.
3. Игнорирование возможности раннего выхода
После того как найдена 1, можно сразу завершить программу. Продолжать обработку уже не нужно.
Вывод
Это очень хорошая задача на базовую работу с входными данными и линейный проход по массиву.
Ключевая мысль проста:
если среди ответов есть хотя бы одна единица, задача считается сложной.
Отсюда получается короткое и естественное решение за O(n).
Комментарии