Задача: Коммерсант, имея стартовый капитал в [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 | Пройден |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <cstdio> #include <cmath> int main() { double k, p, s, years; scanf("%lf %lf %lf", &k, &p, &s); if( s<=k ) { years=0; printf("%ld", years); } else { years = log( s/k )/log( 1 + (p/100) ); //применяя функцию округления до ближайшего большего целого, рассчитать количество лет printf("%2.0lf", ceil(years) ); } return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import java.util.*; import java.lang.*; import java.io.*; import java.math.*; class Ideone { public static void main (String[] args) throws java.lang.Exception { Scanner in = new Scanner(System.in); double k = in.nextDouble(); double p = in.nextDouble(); double s = in.nextDouble(); double years = 0; if(s > k) years = Math.ceil(Math.log(s/k)/Math.log(1+(p/100))); System.out.println(years); } } |
Решение задачи основано на т.н. «формуле сложных процентов»: [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
1. В тестах все числа целые, но выбран тип данных double. Может стоит доработать?
2. Переменные k, p, s в условии лучше тоже сделать в laTeX
Отредактировал отчет:
1. Убрал тесты, рассматривающие случаи, которые выходят за ограничения, указанные в условии задачи.
2. Все математические понятия переписал в LaTeX.
3. Добавил в список тестов случаи с дробными числами.
-Можете прочесть п.2 прошлого комментария?
-Почему магазин не может стоить меньше чем имеется капитала?
— Что значит 1.140 рублей? У рубля вроде мельче сотых (т.е. копеек) нет. Формально там 0 тысячных. — Т.е. не противоречит. Но что Вы имели в виду?
— Логарифмировать можно по любому снованию.
— Если капитал и цена магазина равны нулю, то задача тоже решается.
Постарался учесть все замечания.
1. Исправил.
2. Думал, что из строки «через сколько лет он накопит сумму…» следует, что на данный момент он ей не обладает, хотя это и не обязательно.
3. Выставлял процентную ставку с тремя знаками после запятой, по инерции сделал то же самое с ценами.
4. Думал, что так будет нагляднее, но исправил.
5. Учёл.
— Подкорректировал алгоритм таким образом, чтобы случаи «0 p 0» и [latex]k>s[/latex] обрабатывались корректно.
— В соответствии с алгоритмом изменил код программы.
— Написал тесты, которые подтверждают, что новый алгоритм при данной формализации условий задачи работает корректно.
Засчитано
Теперь осталось только метки (ключевые слова) написать