Редакция для Годы вклада


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.

Автор: montes332

1. Идея

Нужно узнать, через сколько лет вклад из суммы S станет не меньше T, если каждый год сумма увеличивается на floor(cur * p / 100).

Достаточно прямого моделирования процесса по годам:

  • начинаем с cur = S;
  • пока cur < T, прибавляем floor(cur * p / 100) и увеличиваем счётчик лет;
  • как только cur >= T, выводим счётчик.

Главное наблюдение: процесс завершается быстро, потому что прибавка растёт вместе с суммой.


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

Наблюдение 1. Сумма вклада никогда не уменьшается

За один год прибавка равна floor(cur * p / 100) >= 0 (так как p >= 1), значит сумма не убывает.

Наблюдение 2. Число шагов невелико

Как только cur >= 100 / p, прибавка становится не меньше 1. При p >= 1 далее сумма растёт не медленнее, чем на 1% в год, поэтому количество лет ограничено величиной порядка log_{1.01}(T), то есть несколькими тысячами при T <= 10^18. Поэтому простой цикл по годам укладывается в ограничения по времени, и бинарный поиск не нужен.

Наблюдение 3. Возможная недостижимость

Если floor(cur * p / 100) == 0 при cur < T (например, p = 1 и cur < 100), то сумма больше никогда не изменится, и цель T недостижима. В таком случае выводим -1. На корректных тестах (где ответ существует) этот случай не встречается, но решение обязано завершаться, а не зацикливаться.

Наблюдение 4. Переполнение в C++

При cur до 10^18 и p до 100 произведение cur * p достигает 10^20 и не помещается в long long. Поэтому прибавку считаем в __int128: add = (long long)((__int128)cur * p / 100). В Python целые числа неограниченной точности, и этой проблемы нет.


3. Алгоритм

  1. Считываем S, p, T.
  2. Если S >= T, выводим 0.
  3. Инициализируем cur = S, years = 0.
  4. Пока cur < T:
    • add = floor(cur * p / 100);
    • если add == 0, выводим -1 и завершаем (недостижимо);
    • cur += add, years += 1.
  5. Выводим years.

4. Сложность

  • по времени: O(answer), где answer — число лет (не более нескольких тысяч);
  • по памяти: O(1).

5. Код на C++17

#include <iostream>
using namespace std;

int main() {
    long long S, p, T;
    cin >> S >> p >> T;

    if (S >= T) {
        cout << 0 << '\n';
        return 0;
    }

    long long cur = S;
    long long years = 0;
    while (cur < T) {
        long long add = (long long)((__int128)cur * p / 100);
        if (add == 0) {
            cout << -1 << '\n';
            return 0;
        }
        cur += add;
        years++;
    }

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

6. Код на Python 3

S, p, T = map(int, input().split())

if S >= T:
    print(0)
else:
    cur = S
    years = 0
    while cur < T:
        add = cur * p // 100
        if add == 0:
            print(-1)
            break
        cur += add
        years += 1
    else:
        print(years)

Комментарии

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