Дубль#541

Розв’язок

Перевіряємо правила в порядку їхнього пріоритету. Спочатку знаходимо три однакові числа, потім — пару. Лише після цього розглядаємо додавання та віднімання. Наприклад, для 2 2 4 відповідь дорівнює 20, а не 10.

Відсортуємо числа: x \le y \le z. Оскільки вони додатні, сума будь-яких двох більша за кожен із доданків. Тому рівність суми двох чисел третьому можлива лише як x+y=z.

Віднімання не створює інших випадків: якщо p-q=r, то q+r=p. Отже, достатньо перевірити ту саму рівність x+y=z.

Алгоритм

  1. Відсортувати три числа.

  2. Якщо x=z, вивести 30.

  3. Інакше, якщо x=y або y=z, вивести 20.

  4. Інакше, якщо x+y=z, вивести 10.

  5. Інакше вивести 0.

Доведення правильності

Якщо x=z, то з x \le y \le z випливає рівність усіх трьох чисел. Алгоритм правильно застосовує перше правило.

Якщо перша умова хибна, то три числа не можуть бути однаковими. Рівні числа після сортування стоять поруч, тому x=y або y=z виконується тоді й лише тоді, коли є рівно два однакові числа. Алгоритм правильно застосовує друге правило.

Якщо обидві попередні умови хибні, усі числа різні. За наведеним спостереженням дозволена арифметична операція існує тоді й лише тоді, коли x+y=z. Отже, алгоритм правильно нараховує 10 балів, якщо третє правило виконується, і 0 балів у решті випадків. Усі можливі входи розглянуто, тому алгоритм правильний.

Складність

Завжди обробляємо рівно три числа, тому час і додаткова пам’ять становлять . Найбільша сума дорівнює 12, тож типу int достатньо.

Реалізація C++17

#include <algorithm>
#include <array>
#include <iostream>
int main() {
    std::array<int, 3> d{};
    std::cin >> d[0] >> d[1] >> d[2];
    std::sort(d.begin(), d.end());
    int answer;
    if (d[0] == d[2]) answer = 30;
    else if (d[0] == d[1] || d[1] == d[2]) answer = 20;
    else if (d[0] + d[1] == d[2]) answer = 10;
    else answer = 0;
    std::cout << answer << '\n';
}