二分月利率,逐月模拟计息与还款后的剩余本金,使最终余额逼近零。
OJ: luogu
题目 ID: P1163
难度:普及/提高-
标签:二分答案模拟数学python
日期: 2026-07-16 17:49
题意
已知贷款本金、每月还款额和还清所需月数,求按月累计的利率,以百分数输出并保留一位小数。
思路
给定小数形式的月利率 rate,每个月结束后的余额是:
text
balance = balance * (1 + rate) - payment利率越高,最后剩余余额越大。于是可在题目保证的 [0,3] 范围内二分:最终余额不大于零时利率还可以提高,否则应降低。
浮点二分固定执行 100 次,精度足够覆盖 0.1% 的输出要求。
Python 知识
- Python 可以直接混合整数输入和浮点计算,无需显式类型转换本金。
- 固定次数浮点二分结构稳定,不依赖
while right-left > eps的阈值选择。 f"{left * 100:.1f}"同时完成小数转百分数和保留一位小数。/home/rainboy/mycode/hugo-blog/content/program_language/python/oj_input_output_cheatsheet.md:浮点格式化输出。
代码
python
principal, payment, months = map(int, input().split())
def remaining_balance(rate):
balance = principal
for _ in range(months):
balance = balance * (1 + rate) - payment
return balance
left, right = 0.0, 3.0
for _ in range(100):
middle = (left + right) / 2
if remaining_balance(middle) <= 0:
left = middle
else:
right = middle
print(f"{left * 100:.1f}")cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-27 00:00
* update_at: 2026-07-27 00:00
*/
/* P1163 银行贷款 */
/* 二分月利率,逐月模拟还款后剩余本金,使最终余额接近零。 */
#include <bits/stdc++.h>
using namespace std;
double principal; // 本金
double payment; // 每月还款额
int months; // 还清月数
// 给定月利率 rate(小数),计算最终剩余本金
double remaining(double rate) {
double balance = principal;
for (int i = 1; i <= months; i++) {
balance = balance * (1 + rate) - payment;
}
return balance;
}
int main() {
cin >> principal >> payment >> months;
// 利率越高,最终剩余本金越大,单调递增
double l = 0.0, r = 3.0;
// 浮点二分固定 100 次,精度足够
for (int i = 1; i <= 100; i++) {
double mid = (l + r) / 2;
if (remaining(mid) <= 0) {
l = mid; // 利率还能更高
} else {
r = mid;
}
}
// 输出百分数,保留一位小数
printf("%.1f\n", l * 100);
return 0;
}复杂度
每次判定模拟 m 个月,总时间复杂度为
总结
先写出“给定利率后余额如何变化”,再观察最终余额对利率单调递增,就能把反求利率转成浮点二分。