-
分析
变量命名如下:
\(n\) 表示贷款的原值,
\(m\) 表示每月支付的分期付款金额,
\(k\) 表示分期付款还清贷款所需的总月数。
\(p\) 表示贷款的月利率
第 \(1\) 月利率为 \((1+p)\),其还款金额 \(m\) 相当于借款金额 \(\frac{m}{1+p}\)
第 \(2\) 月利率为 \((1+p)^2\),其还款金额 \(m\) 相当于借款金额 \(\frac{m}{(1+p)^2}\)
第 \(3\) 月利率为 \((1+p)^3\),其还款金额 \(m\) 相当于借款金额 \(\frac{m}{(1+p)^3}\)
....
第 \(k\) 月利率为 \((1+p)^k\),其还款金额 \(m\) 相当于借款金额 \(\frac{m}{(1+p)^k}\)
其总共还款金额 \(k*m\) 相当于借款金额 \(s = \sum_{i=1}^{k} \frac{m}{(1+p)^i}\)。
于是有公式, \(s = \sum_{i=1}^{k} \frac{m}{(1+p)^i}=n\)。
所以问题转化为找一个合法的 \(p\),使其满足上述公式。
假定 \(p\) 的可取范围为 \([0,10]\),小数二分该区间即可。
如果 \(s≤n\),则证明 \(p\) 需要降低 --- 即取左区间 \(r=mid\)。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const double eps=1e-4;
double n,m,k;
// 检查利率为 x 时,还款是否 <=n.
bool chk(double x){
double s=0, p=1;
for(int i=1; i<=k; i++){
p *= (1+x);
s += m/p;
}
return s<=n;
}
int main() {
scanf("%lf%lf%lf",&n,&m,&k);
double l=0,r=10;
while(r-l > eps){
double mid=(l+r)/2;
if(chk(mid)) r=mid;
else l=mid;
}
printf("%.1lf",l*100);
return 0;
}
标签:二分,借款,frac,金额,mid,还款,P1163,月利率,小数
From: https://www.cnblogs.com/hellohebin/p/17245774.html