Codeup小白掉坑经验总结之 出租车费 id=1128

2018-01-15 14:22:52来源:网络收集作者:程序诗人人点击

分享

阿里云爆款
Codeup小白掉坑经验总结之 出租车费 id=1128
题目如下
1128: 出租车费
时间限制: 1 Sec内存限制: 32 MB
献花: 113解决: 55

题目描述
某市出租车计价规则如下:起步4公里10元,即使你的行程没超过4公里;接下来的4公里,每公里2元;之后每公里2.4元。行程的最后一段即使不到1公里,也当作1公里计费。
一个乘客可以根据行程公里数合理安排坐车方式来使自己的打车费最小。
例如,整个行程为16公里,乘客应该将行程分成长度相同的两部分,每部分花费18元,总共花费36元。如果坐出租车一次走完全程要花费37.2元。
现在给你整个行程的公里数,请你计算坐出租车的最小花费。


输入
输入包含多组测试数据。每组输入一个正整数n(n<10000000),表示整个行程的公里数。
当n=0时,输入结束。
输出
对于每组输入,输出最小花费。如果需要的话,保留一位小数。
样例输入
3
9
16
0
样例输出
10
20.4
36


唉。。。为我的智商捉急,想算法想了半天,以为这题很难,看!n<10000000!这么大的数,还要分坐多少次出租车,这是得有多麻烦啊!而且,正常人谁会坐一段还停一段(눈_눈)
我简单的思考了一下,四公里以内,肯定是10块钱,4到8公里,那就是10+去掉4公里的公里数乘以2,然后,就是问题所在了,首先,从8~12,坐一次的花费还是最便宜的,但是13时两个相等,大于13就要分成两次了,看起来~~~还行啊,但是。。。。后面每次都要找分裂点吗??下一个分裂点是多少?数字可是1e7这么大啊!于是我出于本能的拒绝继续思考
(゚Д゚*)ノ


最终,我放弃了自我思考,求助度娘。。。参考了一位大神的代码,然后发现,卧槽?这么想的?这么简单的?我还是太辣鸡了(。_。)


原博客链接


自我修改后的代码是这样的


#include
int main()
{
int n;
double fee;
while(~scanf("%d",&n))
{
if(n==0)break;
fee=0;
if(n<4)
fee=10;
if(n>=4&&n<=8)
fee=10+(n-4)*2;
if(n>8)
{
while(n>=8)
{
fee+=18;
n-=8;
}
if(n<=4)
{
fee+=2.4*n;
}
else
{
fee+=10+(n-4)*2;
}
}
if(fee==(int)fee)
printf("%d/n",(int)fee);
else
printf("%.1f/n",fee);
}
return 0;
}

本文只为自己梳理总结思路,为遇到同样问题的同学提供微薄的帮助,不做其他用途。


这个算法,到8公里,思想都是一样的,关键就是八公里之后,这个算法是,不断减去8,直到得到的数小于8,然后判断它是大于4还是小于等于4,根据相应的情况进行运算。
算法思想很容易理解,关键就是,为什么要这样算?贪心算法的证明才是最难的,证明方法一般是用反证法或者数学归纳法,但是我也不会证明啊!所以,我只能这样理解一下这个算法:
对于公里数N
小于等于4公里,10元
大于4公里,小于等于8公里,10+(N-8)*2元
大于8公里,N%8<=4 (N/8)*18+(N%8)*2.4元
大于8公里,N%8>4(N/8)*18+(N%8-4)*2+10元


后面两个判断分支的意思是,如果N%8小于等于4,就在原来分过的这么多次上的其中一次加上这个公里数,自然费用要按照超过8公里的2.4计算,如果N%8大于4小于8,那么就要再增加一次坐车,因为不增加的话,再往原来的次数上算更贵,所以就再来一次,起步10元,多的按照每公里2元算,最终的结果就是这样啦


微信扫一扫

第七城市微信公众平台