本内容纯作者吃饱了没事干做出来的,仅供娱乐和思路参考(当然代码肯定是AC了)
最近我想重新提升一下自己的编程能力,想选一个题量比较精炼的平台,所以就用了洛谷。
题目描述
学校和 yyy 的家之间的距离为 s 米,而 yyy 以 v 米每分钟的速度匀速走向学校。
在上学的路上,yyy 还要额外花费 10 分钟的时间进行垃圾分类。
学校要求必须在上午 8:00 到达,请计算在不迟到的前提下,yyy 最晚能什么时候出门。
由于路途遥远,yyy 可能不得不提前一点出发,但是提前的时间不会超过一天。
输入格式
一行两个正整数 s, v,分别代表路程和速度。
输出格式
输出一个 24 小时制下的时间,代表 yyy 最晚的出发时间。
输出格式为 HH:MM,分别代表该时间的时和分。必须输出两位,不足前面补 0。
如果按照题单来做题的话,这个问题出现在顺序结构这一栏中。因此本人尝试不使用顺序结构以外的其它结构。
按照正常思路首先需要计算行走所花费的时间,也就是路程除以速度加上额外的时间,即s/v+10 。但很显
然,整除运算并没有我们想的这么简单:
如果s能够被v整除,那么就是按照正常的运算;如果不能整除,那么还需要额外花费一分钟的时间,即s/v+10+1。
按照正常思路很明显需要用到条件分支,这里我们可以使用bool值巧妙地得到结果。
t=s/v+10+(bool)(s%v);
接下来就是要把它分别换算成时 和分。
很容易能想到,这里可以分别使用60整除 和60取模来得到所需要的值。
min=t%60;
h=t/60;
接下来就是求出在8:00前能够到达的最晚时间。我们可以将8:00等价于7:60进行运算。因此只需要将小时的数值和分的数值分别与之相减即可。
h=7-h
min=60-min
最终,题目还要求需要用到标准的 HH:MM 格式,因此你可能还需要setw() 和**setfill()**函数进行位置填充。
按照以上的思路,你满怀信心地提交代码,最终成功地发现没有通过。
不知道你发现没有,假如他恰好只花了一个小时的时间,那根据上面的算法,得到的最终结果是 06:60,这非常不科学。所以我们需要进行合适的进位。
首先是对分的数值进行进位,这里也可以使用60取模实现。
min=(60-min)%60
相应的,当min的数值取0的时候,h需要进位。(不存在总时间为0的情况,他还需要分类垃圾)这里可以通过取反来得到需要的bool值。所以我们可以把前面的h修改成:
h=t/60-((bool)(!min))
同时,题目条件说花费的时间不会超过一天,但万一他花费了23个小时 ,那我们根据上面的公式得到的小时数便是**-16**,这不科学。所以我们需要加上24小时防止出现负数;
但如果他花费的时间又小于7小时,那得到的小时数岂不是又大于24了?所以这里我们可以再次进行24取模。
h=(7-h+24)%24
经过上方的调整,我们的代码终于AC了。下面放出完整代码:
//P5707 上学迟到
#include<iostream>
#include<iomanip>
using namespace std;
int main(){
int s,v,t,h,min; cin>>s>>v;
t=s/v+10+(bool)(s%v);
min=t%60;
h=t/60-((bool)(!min));
cout<<setw(2)<<setfill('0')<<(31-h)%24<<":"<<setw(2)<<setfill('0')<<(60-min)%60<<endl;
}
同时我发现有个BUG,我最初写的这篇文章的初版(现已删)在进位时没有将小时数同步加一,也就是花费1小时行走路程的时候输出结果却是 06:00 。但是洛谷并没有这一问题的判断,依旧是让我AC。
总而言之,虽然我的代码看上去十分的简洁。但说实话,哪个人闲着没事干会这样想解题思路,条件分支放在那能不用都是神人了。
不过话又说回来,其实总有一些奇怪的问题的解决方案是需要这样奇怪的解题思路的。
仅供娱乐。