题目相关
题目链接
计蒜客,https://nanti.jisuanke.com/t/T1871。
题目描述
蒜头君从银行贷款了 1000 元钱,月利率为 10%,三个月内分三期还款,那他每次要还款 402.11 元。银行告诉他是这么算的:。
现在已知总贷款数 x 元,每个月还贷 y 元,一共贷款 n 个月,要求计算出贷款者向银行支付的利率,假设利率按月累计。
输入格式
三个用空格隔开的正整数 x,y,n (1≤x,y≤10^5,1≤n≤20),分别表示总贷款数,每月还贷数目,一共的月份。
输出格式
一个实数,表示该贷款的月利率(用百分数表示),四舍五入精确到 0.1%。答案保证不超过 1000%。
样例输入
1000 100 12
样例输出
2.9
题目分析
题目要求
告诉总贷款数 x 元,每个月还贷 y 元,一共贷款 n 个月,要求计算出贷款者向银行支付的利率,假设利率按月累计。从样例输出可以看出,这就是一个标准的浮点数二分题。
样例数据分析
浮点数二分数据分析以前做过,具体可以参考这篇文章,https://blog.csdn.net/justidle/article/details/104620745。这里就不分析了。
而且从题目可以看出,最小的月利率是 0.1%,最大的月利率是 1000%。也就是左边界是 0.001,右边界是 10。精度呢?题目要求四舍五入到 0.1%,也就是小数点后 3 位,因此 EPS 可以去 1e-5 就可以满足要求了。
编程思路
1、编写 check 函数。就是根据题目给的计算公式,用 mid 为利率,计算 n 个月后有多少钱。如果按照 mid 利率算出的钱大于总贷款数 x,则缩小利率。否则放大利率。
2、读入数据。
3、从 left=0.001 到 right=10,套用浮点数二分查找模板,快乐的二分吧。
AC 参考代码
#include <bits/stdc++.h>
using namespace std;
double x;//总贷款数
double y;//每个月还贷
double n;//贷款月份
//以x为利率计算 n 年
bool check(double mid) {
double ans=0;
for (int i=1; i<=n; i++) {
ans += y/pow(1+mid, i);
}
if (ans>x) {
return true;
} else {
return false;
}
}
int main() {
//读入数据
cin>>x>>y>>n;
//浮点数二分
double left = 0.001;
double right = 10;
const double EPS = 1e-5;
double mid;
while (right-left>EPS) {
mid = (left+right)/2;
if (check(mid)) {
left = mid;
} else {
right = mid;
}
}
printf("%.1lf\n", left*100);
return 0;
}
时间复杂度
O(nlogn)。