换种思路去解决,---一道有意思的面试题

题目和代码引用于牛客网,原文网址为https://www.nowcoder.com/question/next?pid=1868636&qid=45185&tid=6243658

题目是这样的:

  在最近几场魔兽争霸赛中,赫柏对自己的表现都不满意。为了尽快提升战力,赫柏来到了雷鸣交易行并找到了幻兽师格丽,打算让格丽为自己的七阶幻兽升星。经过漫长的等待以后,幻兽顺利升到了满星,赫柏很满意,打算给格丽一些小费。

赫柏给小费是有原则的:

1.最终给格丽的钱必须是5的倍数;
2.小费必须占最终支付费用的5%~10%之间(包含边界)。
升星总共耗费A魔卡,赫柏身上带了B魔卡,赫柏想知道他有多少种支付方案可供选择。
注:魔卡是一种货币单位,最终支付费用=本该支付的+小费

  化成简单的表达就是设有3个变量Final,Should,Tip 。Final代表最终支付费用,Should代表本应该支付的,Tip代表小费。

  则:Final = Should + Tip ;  且满足 Final为5的倍数,  Tip为Final的5%-10%(包含边界)

我们很容易就想到用循环来进行枚举,找到合适的结果就+1,最终输出结果,

 

现在来看一个不用循环的代码:

 1 #include<iostream>
 2 #include<math.h>
 3 using namespace std;
 4 int main(){
 5     int A,B,R;
 6     while(cin>>A&&cin>>B){
 7         R=0;
 8         int a=ceil(A/0.95),b=floor(A/0.9);
 9         if(a<=B){
10             if(b>B){
11                 R=B/5-a/5;
12             }else{
13                 R=b/5-a/5;
14             }
15             if(a%5==0)
16                 R++;
17     }
18         cout<<R<<endl;
19     }
20     return 0;
21 }

     首先得到A,B ,A为应该支付的费用,这是确定的。 B为赫柏身上所带的费用。现在我们换种思路,A是确定的,小费所占的比例为5%-10%,那么可以反过来知道,应该支付的也就是A占总费用的90%-95%,那么便可以算出总费用的范围。在代码中,a为A占总费用的95%也就是小费占5%的数值,       b为A占总费用的90%也就是小费占10%的范围;

  对于ceil()和floor()函数分别为向上取整,和向下取整。 作为总费用的起点,将算出的值向上取整,比如为5.6,那么肯定取6,因为5肯定不符合,同样的道理,

对于b来说,作为总费用的终点.比如b取值为5.6。肯定可以达到5,而6是达不到的,所以想下取整。

  首先判断赫柏身上所带的费用B和总费用的起点比,如果B小于a,那么说明钱没带够,也就是说没法支付小费了,直接退出循环。

  如果赫柏带的钱B大于等于总费用的起点a,那么再看赫柏的钱和总费用的终点b相比怎么样,如果B大于等于b那么 则 方案总数= b/5-a/5(咱们后边在来说这个是怎么算的)

  如果赫柏带的钱B<b那么就按总费用为a到B来计算,也就是方案总数 = B/5-a/5

  现在再来看这个方案总数 = b/5-a/5 是怎么算的,这里以赫柏的钱带够了来看,没带够一样的道理,因为最后要求最终付的钱为5的倍数,也就是说总费用每一次+5,每加一次5就是一次新的支付方案,那么求出费用的初始点a用了几个5,在求出终点b用了几个5,他们之差就是多了几个5,也就是有几种方法,由于这样计算吧a是5的倍数的情况也减去了,而a为5的倍数,也就是小费为5%时也是一种情况,所以最后计算时,要把这情况加上,即程序中的R++,最后输出结果R,也就是方案的总数。

     其实还有一个问题没有解决,就是b/5-a/5能不能用(b-a)/5来替换?   假设b-a=5.6,然后除以5等于1,得出结果,但此时并没有考虑a的值,换而言之,这样计算的话没有在满足大于等于a的5的倍数上开始+5,而不管基础就开始在a的基础上加,这样是不正确的。比如刚开始为1,然后加5等于6,你在计算的时候,就会把6当成一种方案计算进去,而真正开始进行加5的应该是5,然后是10,而不是6,11,。再换而言之,(b-a)/5,是对两者的差来进行计算有几个5,没有考虑基础的情况。

 

转载于:https://www.cnblogs.com/songbo/p/6212699.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值