洛谷:P5707 【深基2.例12】上學遲到 (純淨的順序結構方法)

一说米發表於2024-11-03

本內容純作者吃飽了沒事幹做出來的,僅供娛樂和思路參考(當然程式碼肯定是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。

總而言之,雖然我的程式碼看上去十分的簡潔。但說實話,哪個人閒著沒事幹會這樣想解題思路,條件分支放在那能不用都是神人了。

不過話又說回來,其實總有一些奇怪的問題的解決方案是需要這樣奇怪的解題思路的。

僅供娛樂。

相關文章