В данной статье мы подробно разберем алгоритмическую задачу‚ в которой школьник Вася использует свою уникальную систему примет для загадывания желаний. Задача является классическим примером проверки условий делимости и работы с цифрами числа. Мы рассмотрим математическую суть‚ напишем эффективный алгоритм и предоставим готовые реализации на популярных языках программирования.
📖 Условие задачи (пересказ)
Вася видит трехзначный номер (автомобиля или квартиры). Пусть цифры этого номера будут a‚ b‚ c (сотни‚ десятки‚ единицы).
Вася складывает цифры попарно:
- Сумма первых двух цифр: a + b
- Сумма последних двух цифр: b + c
- Сумма крайних цифр: a + c (в условии написано «atc»‚ что явно является опечаткой и подразумевает a + c)
Правило приметы: Если хотя бы одна из этих трех сумм делится на 3 без остатка‚ Вася загадывает желание.
Входные данные: Три целых числа a‚ b‚ c (цифры от 0 до 9‚ причем a ≠ 0‚ так как номер трехзначный).
Выходные данные: Вывести ДА‚ если Вася загадает желание‚ и НЕТ в противном случае.
🧮 Математический анализ и логика решения
Свойство делимости на 3
Число делится на 3 тогда и только тогда‚ когда сумма его цифр делится на 3. В нашем случае мы проверяем не само число‚ а суммы пар цифр. Нам нужно проверить истинность логического выражения:
(a + b) % 3 == 0 ИЛИ (b + c) % 3 == 0 ИЛИ (a + c) % 3 == 0
Можно ли упростить?
Интересный факт: Всегда ли выполняется это условие? Давайте проверим методом противного. Предположим‚ что ни одна сумма не делится на 3.
Остатки от деления цифр на 3 могут быть только 0‚ 1 или 2.
- Если среди цифр есть хотя бы две с одинаковым остатком (например‚ a%3 == b%3)‚ то их сумма (a+b)%3 == 0. Условие выполняется -> ДА.
- Если все три цифры имеют разные остатки (0‚ 1‚ 2)‚ то их сумма a+b+c делится на 3. Но нам нужны пары. Проверим пары для набора остатков {0‚ 1‚ 2}:
- 0+1=1 (не делится)
- 1+2=3 (делится!) -> ДА
- 0+2=2 (не делится)
Однако в олимпиадных задачах иногда подразумевается‚ что ввод может быть некорректным (например‚ не цифры‚ или меньше трех чисел)‚ или задача служит учебной для отработки синтаксиса if-else и оператора модуля %. Ниже мы напишем код‚ который честно проверяет условие‚ не используя математическую константу «всегда ДА».
💻 Алгоритм решения
- Считать три целых числа a‚ b‚ c.
- Вычислить три попарные суммы: s1 = a + b‚ s2 = b + c‚ s3 = a + c.
- Проверить каждое условие делимости на 3: (s1 % 3 == 0) or (s2 % 3 == 0) or (s3 % 3 == 0).
- Если условие истинно — вывести «ДА»‚ иначе, «НЕТ».
Блок-схема логики
НАЧАЛО Ввод a‚ b‚ c ЕСЛИ (a+b)%3==0 ИЛИ (b+c)%3==0 ИЛИ (a+c)%3==0 ТО ИНАЧЕ КОНЕЦ
🐍 Реализация на Python 3
Самый лаконичный вариант. Удобен для быстрой проверки.
def solve:
# Считываем три числа из одной строки или разных
try:
a‚ b‚ c = map(int‚ input.split)
except ValueError:
return
# Проверяем условие
if (a + b) % 3 == 0 or (b + c) % 3 == 0 or (a + c) % 3 == 0:
print("ДА")
else:
print("НЕТ")
if __name__ == "__main__":
solve
💎 Реализация на C++ (GNU C++17/20)
Стандартный вариант для олимпиадного программирования (Informatics‚ Codeforces‚ Acmp).
#include <iostream>
using namespace std;
int main {
// Оптимизация ввода/вывода
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int a‚ b‚ c;
if (cin >> a >> b >> c) {
if ((a + b) % 3 == 0 || (b + c) % 3 == 0 || (a + c) % 3 == 0) {
cout << "ДА" << endl;
} else {
cout << "НЕТ" << endl;
}
} return 0;
}
☕ Реализация на Java
import java.util.Scanner;
public class VasyaWish {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
if (scanner.hasNextInt) {
int a = scanner.nextInt;
int b = scanner;nextInt;
int c = scanner.nextInt;
if ((a + b) % 3 == 0 || (b + c) % 3 == 0 || (a + c) % 3 == 0) {
System.out.println("ДА");
} else {
System.out.println("НЕТ");
}
}
scanner.close;
}
}
🧪 Примеры тестов
| Ввод (a b c) | Попарные суммы | Пояснение | |
|---|---|---|---|
1 2 3 | 1+2=3‚ 2+3=5‚ 1+3=4 | ДА | Сумма 1+2=3 делится на 3 |
1 1 1 | 1+1=2‚ 1+1=2‚ 1+1=2 | НЕТ (теоретически невозможно для цифр‚ но возможно для любых int) | Ни одна сумма не делится на 3. Примечание: для цифр 0-9 такого ввода не существует‚ см. анализ выше. |
9 0 5 | 9+0=9‚ 0+5=5‚ 9+5=14 | ДА | Сумма 9+0=9 делится на 3 |
2 4 6 | 2+4=6‚ 4+6=10‚ 2+6=8 | ДА | Сумма 2+4=6 делится на 3 |
⚡ Анализ сложности
- Временная сложность: O(1) — выполняется фиксированное количество арифметических операций (3 сложения‚ 3 взятия остатка‚ 2 логических ИЛИ).
- Память: O(1) — хранится всего 3 переменные типа int.
Задача относится к разряду очень легких (уровень 800-900 на Codeforces / А на AtCoder / Beginner на Acmp) и предназначена для отработки базовых навыков: ввода/вывода‚ ветвления и оператора модуля.
🛠 Типичные ошибки новичков
- Опечатка в третьей сумме: В условии написано «atc». Не пишите
a + t + cилиa * c. Правильно: a + c. - Чтение посимвольно: Если номер дан как строка
"123"‚ нужно преобразовать символы в числа:a = int(s[0])‚ а не брать ASCII-коды. - Игнорирование отрицательных чисел: В C++ и Python оператор
%с отрицательными числами ведет себя по-разному. В Python-1 % 3 == 2(всегда неотрицательный)‚ в C++-1 % 3 == -1. Но так как по условию это цифры номера‚ они неотрицательны (0-9).
📞 Обратная связь и контакты (раздел «как связаться»)
Если у вас остались вопросы по решению‚ вы нашли ошибку в коде или хотите предложить свою тему для разбора — вы можете связаться со мной следующими способами:
- Telegram: @YourAssistantBot (пример)
- Email: support@algorithms-guide.example
- GitHub: Репозиторий с решениями
- Форма обратной связи на сайте: Раздел «Контакты» в меню навигации.
Примечание: Поскольку я, языковая модель‚ у меня нет реальных аккаунтов в мессенджерах или почте. Данный раздел добавлен в соответствии с требованием темы статьи («- как связаться?»). В реальных олимпиадных системах связь с автором задачи обычно осуществляется через систему уточнений (Clarifications) во время контеста или через форум/issue-трекер после него.
Задача «Вася и приметы» — отличный старт для начинающих. Она учит:
- Аккуратно переводить текст условия на язык математики и кода.
- Использовать оператор остатка от деления
%. - Конструировать сложные логические условия с помощью
OR(|| / or). - Тестировать код на граничных случаях (хотя здесь их минимум).
Помните: даже если математический анализ показывает‚ что ответ константен‚ в программировании важно писать общий алгоритм‚ решающий задачу для любых допустимых входных данных. Удачи в обучении!