AC代码————
#include <bits/stdc++.h>
using namespace std;
int main()
{
int loan,pay,month;
double l=0,r=5,mid,t;
cin>>loan>>pay>>month;
while(l<r){
mid=(l+r)/2;
if(r-l<0.0001){
break;
}
t=loan;
for(int i=0;i<month;i++)
{
t=t*(1+mid)-pay;
}
if(t>0) r=mid;
else if(t<0) l=mid;
else{
printf("%.1f",mid*100);
return 0;
}
}
printf("%.1f",mid*100);
return 0;
}
https://vjudge.net/problem/%E6%B4%9B%E8%B0%B7-P1163
显而易见,我要复习二分哈哈,先来复习二分查找,下一篇再复习二分答案^_^。
提问!二分查找是什么!
自问自答!二分查找是在一个已知的有序数据集上进行二分地查找。注意注意,一定要有序!
二分查找的基本思想是将n个元素分成大致相等的两部分,取a[n/2]与x做比较,如果x=a[n/2],则找到x,算法中止;如果x<a[n/2],则只要在数组a的左半部分继续搜索x,如果x>a[n/2],则只要在数组a的右半部搜索x(一个师哥说的,我小抄一下/respect)。
接下来段示例代码~
int search(int a[],int n,int value) //有序数组,数组长度,要找的东西
{
int l=0;
int r=n-1;
while(l<=r){
int mid=(l+r)/2; //可优化为l+(r-l)>>1
if(a[mid]==value) return mid;
else if(a[mid]<value) l=mid+1;
else r=mid-1;
}
return -1;
}
这里就不写递归写法了,递归写法稍微长一点QAQ(真的不是我懒)
如果要判断一个元素第一次出现的位置可以往循环里面加条件,就是当找到一个等于value的位置时判断一下这个位置是否为零或者这个位置前面那个位置是否为value,为零和前一个不为value这两个条件成立其一就能输出mid,若不能成立就继续二分,让r=mid-1,找元素最后出现的位置同理。
当然,我们还可以用stl的二分查找函数:
1.binary_search(begin,end,num):查找某个元素是否出现。 功能:在数组中以二分法检索的方式查找,若在数组(要求数组元素非递减)中查找到indx元素则真,若查找不到则返回值为假。
2.lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
3.upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
回到这道题使用的是浮点数二分,贴个模板在下面————
while(r-l>1e-5){
double mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid;
}
(虽然我没有太按模板来QAQ)
如何还钱的方法大家自己理解一下,我感觉我不太会描述,就是设定一下利率,然后就按他要求的月份还钱,每个月剩下的钱要乘以1+利率再减这个人每个月要还的钱,循环完如果为负数就是利率小了,还的钱多了,如果为正数就是利率大了,还的钱少了,就调整利率继续二分。
这道题答案的出口有两个出口,一个当然就是正好还完,还有一个就是利率的精度达到要求,输出就完事了。
就酱紫,挥挥~