本內容純作者吃飽了沒事幹做出來的,僅供娛樂和思路參考(當然程式碼肯定是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。
總而言之,雖然我的程式碼看上去十分的簡潔。但說實話,哪個人閒著沒事幹會這樣想解題思路,條件分支放在那能不用都是神人了。
不過話又說回來,其實總有一些奇怪的問題的解決方案是需要這樣奇怪的解題思路的。
僅供娛樂。