洛谷P1163银行贷款(经典二分答案入门题)

题目链接:

 

跟最大值最小化(最小值最大化)略有不同,枚举利率满足=0刚好还完即可(坑点,浮点数有精度误差,控制好),但大致上一样。(其实我是先写暴力枚举再改为二分枚举的。。)

 

注意几点

1.经济学常识,利率累加每月的额外支付不一样(明白那个计算公式相当于judge函数)。

2.找到一个满足的就可以退出,不用再像最小值最大化再向右尝试了。

3.控制好精度问题,<0.001有个wa,<0.0001即可

4.和那个问题不同,可能过程中没有break直到最后退出,这时特判一下=r或l即可

 

 1 #include <iostream>
 2 #include <iomanip>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     ios::sync_with_stdio(false); cin.tie(0);
 8     
 9     double a,b,c;
10     cin>>a>>b>>c;
11     
12     double i=0,ans=0;
13     double l=0,r=5;
14     while(l<=r)
15     {
16         double mid=(l+r)/2;
17         //cout<<l<<' '<<r<<' '<<mid<<endl;
18         double x=a;
19         for(int j=1;j<=c;j++)
20             x=x*(1+mid)-b;
21         
22         if(x>=-0.0001 && x<=0.0001)
23         {
24             ans=mid;
25             break;
26         } 
27         else
28         {
29             if(x>0) r=mid-0.0001;
30             else l=mid+0.0001;
31         }
32              
33     }
34     if(l>r) ans=r;35     
36     cout<<setiosflags(ios::fixed)<<setprecision(1)<<ans*100<<endl;
37     
38     return 0;
39     
40 }

 

与之相似的还有小车问题

该题2种解法:

1.数学列解方程(有些不太好想方程不太好列,不推荐)

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <iomanip>
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     double s,a,b;
10     cin>>s>>a>>b;
11     
12     double x=(a+b)*s/(3*a+b);
13     double t=x/b+(s-x)/a;
14     
15     cout<<setiosflags(ios::fixed)<<setprecision(6)<<t<<endl;
16     
17     return 0;
18 }

2.枚举答案二分(无脑枚举x点位置再控制精度即可,推荐简单)(比较锻炼代码能力和思维能力==要的就是这种分析解决问题的能力)

 1 #include <iostream>
 2 #include <iomanip>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     ios::sync_with_stdio(false); cin.tie(0);
 8     
 9     double s,a,b;
10     cin>>s>>a>>b;
11     
12     double ans=0;
13     double l=0,r=s;
14     while(l<=r)
15     {
16         double mid=(l+r)/2;
17         //cout<<l<<' '<<r<<' '<<mid<<endl;
18         double t2=mid/b+(s-mid)/a;
19         double t1=mid/b+(mid-a*mid/b)/(a+b)+(s-a*mid/b-a*(mid-a*mid/b)/(a+b))/b;
20         double t=t2-t1;
21         //cout<<t2<<' '<<t1<<endl;
22         
23         if(t>=-0.000001 && t<=0.000001)
24         {
25             ans=mid;
26             break;
27         } 
28         else
29         {
30             if(t<-0.000001) r=mid-0.000001;
31             else if(t>0.000001) l=mid+0.000001;
32         }
33              
34     }
35     //if(l>r) ans=r;
36     
37     //cout<<setiosflags(ios::fixed)<<setprecision(6)<<ans<<endl;
38     double p=ans/b+(s-ans)/a;
39     cout<<setiosflags(ios::fixed)<<setprecision(6)<<p<<endl;
40     
41     
42     return 0;
43 }

 

完。

转载于:https://www.cnblogs.com/redblackk/p/10034181.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值