Задача 579A · Raising Bacteria (Выращиваем бактерии)
← К списку тем
Тренажёр · Поразрядные операции

Как вырастить ровно x бактерий?

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

Задача 579A · Raising Bacteria (Выращиваем бактерии)

Сначала ящик пуст. Каждое утро в него разрешено положить сколько угодно бактерий. Каждую ночь каждая бактерия делится надвое. Нужно в какой-то момент получить ровно x бактерий. Какое наименьшее число бактерий придётся положить в ящик за всё время?

Ввод: одно целое число x, 1 ≤ x ≤ 10⁹. Вывод: одно число — минимум добавленных бактерий. Например, для 5 ответ 2, а для 8 ответ 1.

Мы будем строить один оптимальный вариант: утром добавлять 0 или 1 бактерию. Одна бактерия, добавленная раньше, успеет несколько раз удвоиться.

Симуляция: проживём задачу по дням

Выбери цель, попробуй предсказать добавление на ближайшее утро и нажимай «Следующий день». Ночь между днями симуляция учитывает сама.

Быстрый выбор:

Цель в двоичной записи: 1101₂

12³12²02¹12⁰

Каждый разряд: верхняя цифра — 0 или 1; снизу — сколько эта единица даст к последнему дню. Жёлтым отмечен следующий разряд.

Перед первым утром

Ящик пуст. Начни опыт, чтобы узнать, сколько добавлять утром.

За прошедшую ночьНочи ещё не было
После добавления утром0 бактерий
Всего добавлено0 бактерий

Каждая точка обозначает одну бактерию. Для больших чисел показана лишь часть точек; точное количество написано выше.

Сколько добавим в день 1?

 

День 0 из 4
Если кнопки недоступны: покажи разбор числа 13

13 = 1101₂. День 1: добавить 1 → 1. Ночь: 1 → 2. День 2: добавить 1 → 3. Ночь: 3 → 6. День 3: добавить 0 → 6. Ночь: 6 → 12. День 4: добавить 1 → 13. Всего добавлено 3 бактерии.

Как узнать ответ без симуляции?

Двоичная запись 13 = 1101₂ означает 13 = 8 + 4 + 1. Утром первого дня добавляем бактерию, которая к концу даст 8; второго — ту, что даст 4; третьего — никого; четвёртого — бактерию, которая даст 1. Ответ: три единицы в записи 1101.

Для любого x действует то же правило: ответ равен количеству единиц в двоичной записи x.

Почему нельзя добавить ещё меньше?

Каждая бактерия, которую мы положили в ящик, к нужному моменту даст 1, 2, 4, 8 и так далее бактерий: её потомки удваиваются ночью. Если две добавленные бактерии дали равные группы, например 4 и 4, их можно мысленно объединить в 8. Такое объединение уменьшает число слагаемых. В конце останутся именно степени двойки из двоичной записи x. Значит, единиц в этой записи не может быть больше, чем добавленных бактерий. Наша симуляция достигает этого количества — меньше уже нельзя.

Решение для отправки

Программа считает единицы в двоичной записи числа. Выражение x & 1 проверяет крайний правый бит, а x >>= 1 убирает его.

Симуляция читает биты слева направо, чтобы показать дни. Код читает их справа налево — на количество единиц порядок не влияет.

Показать код на C++ и Python
C++
#include <iostream>
using namespace std;

int main() {
 int x, answer = 0;
 cin >> x;
 while (x > 0) {
 answer += (x & 1);
 x >>= 1;
 }
 cout << answer << '\n';
}
Python
x = int(input())
answer = 0
while x > 0:
 answer += x & 1
 x >>= 1
print(answer)

Самопроверка перед отправкой: запусти программу для 5 и 8. Должны получиться 2 и 1.

Открыть Raising Bacteria на Codeforces и отправить решение ↗
Категория: Algorithms | Добавил: bzfar77 (Сегодня)
Просмотров: 7 | Теги: 579a, raising bacteria, решение на codeforces, двоичная система, тренажер | Рейтинг: 0.0/0
Всего комментариев: 0
avatar