Банки с таблетками
Условие
У вас есть 20 банок с таблетками. В 19 банках таблетки весят 1 грамм, в одной банке - 1.1 грамма. У вас есть весы, которые можно использовать только один раз. Как найти тяжелую банку за одно взвешивание?
Вопрос
Опишите алгоритм решения.
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение
Описание задачи
Классическая логическая задача, которая проверяет творческое мышление и умение выбирать оптимальную стратегию при ограниченных ресурсах. Нужно использовать весы только один раз, чтобы найти одну тяжелую банку среди 20.
Ключевая идея
Вместо поиска отдельной банки используем кодирование информации через количество таблеток с каждой банки. Таким образом, одно взвешивание даст нам информацию о всех банках сразу.
Алгоритм решения
Шаг 1: Подготовка
- Нумеруем банки от 1 до 20
Шаг 2: Взятие таблеток
- Из банки №1 берём 1 таблетку
- Из банки №2 берём 2 таблетки
- Из банки №3 берём 3 таблетки
- ...
- Из банки №20 берём 20 таблеток
Всего возьмём: 1 + 2 + 3 + ... + 20 = 20 × 21 / 2 = 210 таблеток
Шаг 3: Взвешивание
- Кладём все 210 таблеток на весы
- Записываем результат в граммах
Шаг 4: Вычисление ответа
Если бы все таблетки весили 1 грамм, общий вес был бы 210 граммов.
Если результат на весах показывает вес W граммов, то:
- Лишний вес = W - 210 граммов
- Лишний вес = количество таблеток по 1.1 г вместо 1 г
- Лишний вес = (номер тяжелой банки) × 0.1 грамма
Следовательно:
Номер тяжелой банки = (W - 210) / 0.1
Ор в целых числах:
Номер тяжелой банки = (W × 10 - 2100) / 1
Пример
Предположим, тяжелая банка - это банка №7.
Ожидаемый вес: 210 + 7 × 0.1 = 210 + 0.7 = 210.7 граммов
Результат на весах: 210.7 г
Вычисление: (210.7 - 210) / 0.1 = 0.7 / 0.1 = 7 ✓
Почему это работает
- Информационное кодирование: Каждая банка представлена уникальным количеством таблеток
- Линейная функция: Вес прямо пропорционален номеру банки
- Однозначность: Только одна банка даёт ровно один лишний вес
- Одно взвешивание: Вся информация получается за одно действие
Обобщение алгоритма
Для N банок, где одна весит W1, остальные весят W0:
def find_heavy_item(n, weights_normal):
"""
n - количество банок
weights_normal - нормальный вес таблетки
Из банки i берём i таблеток
"""
expected_weight = sum(range(1, n + 1)) * weights_normal
# После взвешивания получаем actual_weight
# excess = actual_weight - expected_weight
# heavy_item_number = excess / weight_difference
return None
Альтернативные варианты задачи
Вариант 2: Если весы показывают только целые граммы:
- Используем 0.01 g разницу вместо 0.1 g
- Результат будет менее точным, может потребоваться рounding
Вариант 3: Если неизвестно, в какую сторону разница:
- Используем нечётные и чётные номера по-разному
- Или применяем алгоритм знакомого весовым кодам (весовые коды Фибоначчи)
Почему это сложнее с двумя взвешиваниями
Если разрешить два взвешивания, задача решается информационно-теоретическим подходом:
- При первом взвешивании разделяем 20 банок на 3 группы
- В худшем случае 7 банок в одной группе
- При втором взвешивании разделяем её на 3 части
- Информационная сложность: log3(20) ≈ 2.73 взвешивания минимум
Ключевые моменты решения
- Творческость: Не сравниваем банки напрямую, кодируем информацию через количество
- Математика: Используем свойства арифметической прогрессии
- Эффективность: Максимально используем информацию из одного взвешивания
- Универсальность: Метод работает для любого N банок и любой разницы в весе