e-olymp 634. Вклад «Антикризисный»

Задача

Постоянные клиенты одного очень крупного банка (ООКБ) недавно получили возможность открыть новый вклад — «Антикризисный». Этот вклад отличается непростой схемой начисления процентов, поэтому вам, как единственному сотруднику ИТ-отдела банка, было поручено написание программы, которая будет вычислять сумму вклада с начисленными процентами.

Вклад «Антикризисный» может быть открыт на любой срок, но дата окончания вклада должна быть не позже $31$ декабря $2009$ года, процентная ставка по вкладу составляет $p$ процентов годовых. Это означает, что если в начале некоторого периода в $d$ дней, в течение которого сумма вклада не менялась, сумма вклада составляла $x$ рублей, то по окончании этого периода она будет составлять $x\cdot\left(1+\frac{p}{100}\cdot\frac{d}{365}\right)$.

Начисление процентов на вклад осуществляется ежемесячно, в последний день месяца (или в последний день действия вклада), при этом сумма процентов присоединяется ко вкладу. Таким образом, если на первое мая сумма вклада составляла $x$ рублей, то $31$ мая ко вкладу будет присоединено $x\cdot\left(\frac{p}{100}\right)\cdot\left(\frac{31}{365}\right)$ рублей, и на первое июня сумма вклада составит $x\cdot\left(1+\left(\frac{p}{100}\right)\cdot\left(\frac{31}{365}\right)\right)$, а в июне проценты будут начисляться уже на эту сумму.

Если же последний день вклада был $20$ мая, то в этот день ко вкладу будет присоединено $x\cdot\left(\frac{p}{100}\right)\cdot\left(\frac{20}{365}\right)$ рублей, а сумма вклада, которую получит клиент банка составит $x\cdot\left(1+\left(\frac{p}{100}\right)\cdot\left(\frac{20}{365}\right)\right)$. Аналогично выполняются расчеты и для случая, когда вклад был открыт не в первый день месяца. Так, например, если вклад был открыт $18$ февраля, то $28$ февраля к сумме вклада будет присоединено $x\cdot\left(\frac{p}{100}\right)\cdot\left(\frac{11}{365}\right)$ рублей, а если же он был открыт $28$ февраля, то в тот же день $28$ февраля к сумме будет присоединено $x\cdot\left(\frac{p}{100}\right)\cdot\left(\frac{1}{365}\right)$ рублей.

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

Входные данные

Первая строка входного файла содержит три целых числа: исходную сумму вклада $x$, процентную ставку $p$ и длительность вклада $d \left(1 ≤ x ≤ 100000, 1 ≤ p ≤ 200, 1 ≤ d ≤ 365\right)$. Вторая строка входного файла содержит дату открытия вклада в формате «день-месяц-год». День и месяц обозначаются числами, при этом у чисел, меньших десяти, присутствуют ведущие нули. Гарантируется,что вклад открыт в $2009$ году, и дата его окончания также находится в $2009$ году.

Выходные данные

В выходной файл выведите ответ на задачу c точностью $6$ знаков после десятичной точки.

Тесты

# Входные данные Выходные данные
1 1000 10 27
18-07-2009
1007.410921
2 1000 12 70
29-06-2009
1023.172779
3 1000 12 37
17-08-2009
1012.200053
4 1000 15 37
21-10-2009
1015.253781
5 1000 15 85
12-08-2009
1035.351224

Код

Решение задачи

Основная проблема в том, что каждый месяц вкладчик получает процент от своего вклада, который считается в цикле. Но процент берётся не от вклада, а от новой суммы, полученной в прошлом месяце, поэтому каждый раз необходимо помнить про уже имеющиеся деньги, чтобы получать каждый месяц новую сумму уже с процентом.

Ссылки

Условие задачи на e-olymp
Код решения на ideone

Ю3.5

Задача Ю3.5. Коммерция. Предприниматель, начав дело, взял кредит размером [latex]k[/latex] рублей, под [latex]p[/latex] процентов годовых и вложил его в своё дело. По прогнозам, его дело должно давать прибыль [latex]r[/latex] рублей в год. Сможет ли он накопить сумму, достаточную для погашения кредита, и если да, то через сколько лет?

[latex]k[/latex] [latex]p[/latex] [latex]r[/latex] [latex]n[/latex] Комментарий.
1800 50 1000 Кредит не будет погашен.
800000 15 40000 Кредит не будет погашен.
1000 5 400 3 Тест пройден.
1500 3,5 400 5 Тест пройден.

Код программы (C++):

Java:

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

Изначально запускается цикл, который основан на сравнении дохода за несколько лет [latex]nr[/latex] и размера кредита, которого он достигнет за эти годы (вычисляется по формуле сложных процентов: [latex]k(1+\frac{p}{100})^{n}[/latex]).

Затем программа проверяет, как возрастают доходы и долг за год. Если скорость роста доходов не превышает скорость роста долга, то программа выдаёт ошибку, или «кредит не будет погашен», после чего возвращается 0 и программа считается успешно завершённой. В противном случае цикл повторяется, а по его окончании на экран выводится количество лет, за которые долг можно будет погасить.

Проверить код можно здесь (C++) и здесь (Java).

Ю1.6

Задача: Коммерсант, имея стартовый капитал k, занялся бизнесом, который ежемесячно увеличивал капитал на p%. Через сколько лет* он накопит сумму s, достаточную для покупки собственного магазина?

k p s m (месяцы)  Коменнтарий:
0 50 500  — No money — no honey
10 0 500 Это не бизнес
50 50 0 0  Логично, программа работает, вводить частный случай не стал.
1000 5 500 9 Пройден
30 15 500 21 Пройден
30 150 500 4 Пройден
5.556 49.04 193.6 9 Пройден

 

 

Решение выполняется с помощью цикла while, который выполняет циклы пока заданное условие правда (см. 12).

Алгоритм цикла:

  1. Цикл работает, пока сумма сложных процентов меньше, чем сумма.

2. Т.к. процент сложный, то он должен изменяться с каждым циклом. Для этого я ввел вспомогательную переменную v.

где k — капитал, pk — сумма сложных процентов.

  1. Делаем сумму сложных процентов

  1. Добавляем месяцы, пока pk не станет большей или равной s.

Вывод: таким образом код работает независимо от того, какой капитал, какой процент или какая сумма. Не беря во внимание частные случаи, код для своей задачи универсален.

 

Частные случаи:

  1. Когда k = 0. Такая ситуация не имеет логического значения ни в коде, ни в жизни. По этому я её обыграл с помощью if. Код не работает

  2. Когда p = 0. Аналогично первому, логики нет. Код не работает

  3. Когда s = 0. В таком случае, магазин бесплатен.  Код работает

 

* — работал в месяцах, так удобней, ибо месячный процент

 

А вообще, время 5 утра. А я только осознал, что у меня 1.16, а не 1.6. Но пусть будет =)

 

 

Ю1.6

Задача:  Коммерсант, имея стартовый капитал в [latex]k[/latex] рублей, занялся торговлей, которая ежемесячно увеличивает капитал на [latex]p%[/latex]. Через сколько лет он накопит сумму [latex]s[/latex], достаточную для покупки собственного магазина?

[latex]k[/latex] [latex]p[/latex]  [latex]s[/latex] [latex]years[/latex] Комментарий:
0 10 0 0 Пройден
 20 10 20 0 Пройден.
 20  10  30 5 Пройден
0.6 30 21 14 Пройден
1.14 0.08 40.00 4450 Пройден
1.14 83.2 30 6 Пройден
1000 20 800 0 Пройден

 

 

 

Решение задачи основано на т.н. «формуле сложных процентов»: [latex]s=k(1+\frac {p}{100})^{years}[/latex].
По условию задачи, необходимо определить значение переменной years, с учётом следующих ограничений:
[latex]k \ge 0[/latex], [latex]p \ge 0[/latex], [latex]s \ge 0[/latex].
Если [latex]s \le k[/latex], то коммерсант уже может позволить себе покупку, следовательно, [latex]years = 0[/latex].
В противном случае, необходимо прологарифмировать левую и правую часть выражения.
Приведя его к удобному виду, получим:
[latex]\frac { s }{ k }=(1+\frac {p}{100})^{years}[/latex]
[latex]\ln { (1 + \frac { p }{ 100 })^{ years } }= \ln{ (\frac { s }{ k }) }[/latex]
В конечном итоге, получаем:
[latex]years=\frac { \ln { \frac {s}{k} } }{ \ln { (1+\frac { p }{ 100 }) } }[/latex]

В программе использован тип данных с плавающей точкой и двойной точностью.
Выбор продиктован требованиями функций заголовочного файла cmath.
Для выполнения программы и проверки тестов можно воспользоваться следующим объектом.
Реализация на Java: http://ideone.com/wbe8Ah