Редакция для Годы вклада
Submitting an official solution before solving the problem yourself is a bannable offence.
Автор:
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. Алгоритм
- Считываем
S,p,T. - Если
S >= T, выводим0. - Инициализируем
cur = S,years = 0. - Пока
cur < T:add = floor(cur * p / 100);- если
add == 0, выводим-1и завершаем (недостижимо); cur += add,years += 1.
- Выводим
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)
Комментарии