Редакция для Улитка в колодце


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

1. Идея

Нужно определить, на какой день улитка впервые достигнет высоты не меньше H.

Наивно можно было бы день за днём считать её положение:

  • днём улитка поднимается на U,
  • ночью сползает на D.

Но ограничения большие: H, U, D могут быть до 10^9, поэтому долго моделировать по дням нельзя.

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


2. Наблюдения

Наблюдение 1

Если за первый же день улитка поднимается на высоту H или выше, то ответ сразу 1.

То есть если U >= H, то улитка выберется в первый день.


Наблюдение 2

Если в какой-то день улитка ещё не выбралась, то после ночи её высота увеличивается на U - D.

Почему именно так?

  • днём она поднимается на U,
  • ночью сползает на D,
  • итог за полный день и ночь: U - D.

Так как по условию U > D, улитка всё-таки постепенно движется вверх.


Наблюдение 3

Последний день отличается от остальных.

В последний день улитка:

  • начинает день на некоторой высоте,
  • поднимается на U,
  • если достигает H, то сразу выбирается,
  • ночью уже не соскальзывает.

Значит удобно отдельно посчитать:

  • сколько полных циклов "день + ночь" нужно сделать до последнего дня,
  • а потом прибавить ещё один, последний день.

3. Алгоритм

Пусть первый случай U >= H уже обработан.

Тогда улитка не может выбраться в первый день, значит U < H.

Обозначим:

  • daily = U - D — чистый прирост за один полный день и ночь,
  • need = H - U — сколько ещё не хватает до края после подъёма в последний день.

Теперь нужно понять, сколько дней улитка должна прожить до последнего дня.

Перед последним днём высота улитки утром должна быть такой, чтобы после подъёма на U она достигла H.

То есть утром последнего дня её высота должна быть не меньше H - U.

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

Это количество равно:

  • ceil(need / daily)

Для целых чисел это считается так:

  • (need + daily - 1) / daily в C++,
  • (need + daily - 1) // daily в Python.

Это число — количество дней до последнего дня. Тогда ответ:

  • days_before_last + 1

4. Почему это работает

Рассмотрим высоту улитки утром каждого дня.

  • Утром первого дня высота равна 0.
  • Если улитка не выбралась в этот день, то после ночи её высота станет U - D.
  • Если не выбралась и во второй день, то после второй ночи высота станет 2 * (U - D).
  • И так далее.

Значит после k полных циклов "день + ночь" высота утром следующего дня равна:

  • k * (U - D)

Чтобы в следующий день выбраться, нужно:

  • k * (U - D) + U >= H

Переносим U вправо:

  • k * (U - D) >= H - U

То есть нужно минимальное целое k, для которого это выполняется. Это и есть:

  • ceil((H - U) / (U - D))

После этих k полных циклов наступает ещё один день, в который улитка выбирается. Поэтому итоговый ответ:

  • k + 1

Если же U >= H, то формула для "дней до последнего" уже не нужна, потому что последний день — это сразу первый.


5. Сложность

Алгоритм выполняет только несколько арифметических операций.

  • Время: O(1)
  • Память: O(1)

6. Код на C++17

#include <iostream>
using namespace std;

int main() {
    long long H, U, D;
    cin >> H >> U >> D;

    if (U >= H) {
        cout << 1 << '\n';
        return 0;
    }

    long long daily = U - D;
    long long need = H - U;
    long long days_before_last = (need + daily - 1) / daily;
    long long answer = days_before_last + 1;

    cout << answer << '\n';
    return 0;
}

7. Код на Python 3

H, U, D = map(int, input().split())

if U >= H:
    print(1)
else:
    daily = U - D
    need = H - U
    days_before_last = (need + daily - 1) // daily
    print(days_before_last + 1)

Комментарии

Еще нет ни одного комментария.