03|時間換算
相關主題: C 基礎速查、資料型態與範圍、C 與 C++ 的關係
這題在練什麼
Section titled “這題在練什麼”整數除法 / 和取餘數 %,以及 printf 的補零格式。
我的解法思路
Section titled “我的解法思路”1 小時 = 3600 秒,1 分鐘 = 60 秒:
| 要算的 | 算式 | 例:3725 秒 |
|---|---|---|
| 小時 | seconds / 3600 | 3725 / 3600 = 1 |
| 分鐘 | (seconds % 3600) / 60 | 125 / 60 = 2 |
| 秒 | seconds % 60 | 3725 % 60 = 5 |
整數除法會直接捨去小數部分,% 拿到的是餘數。最後用 printf("%d:%02d:%02d\n", ...) 輸出成 1:02:05。
秒數最大是 10^9,換算成小時約 27 萬,用 int 裝得下(上限約 21 億),所以這題不需要 long long。
%01d 和 %d。 我第一次通過時用的是 %01d,後來改成 %d。兩種寫法都正確,因為效果完全一樣。printf 的格式是 %[旗標][寬度]d:
| 格式 | 意思 | 印 5 | 印 125 |
|---|---|---|---|
%d | 照原樣印 | 5 | 125 |
%2d | 至少 2 格,不夠的話左邊補空白 | 5 | 125 |
%02d | 至少 2 格,不夠的話左邊補 0 | 05 | 125 |
%01d | 至少 1 格,不夠補 0 | 5 | 125 |
任何數字至少都有 1 位數,所以 %01d 永遠不會補任何東西,等於 %d。小時不需要補零,用 %d;分和秒要固定兩位數,用 %02d。
其他常見的坑:
- 用
%2d會印出1: 2: 5(補的是空白),答案錯誤。 - 寬度只是「至少」,數字比寬度長時不會被截斷。小時是 277777 時,
%02d一樣會完整印出277777。 - C++ 的寫法是
std::setw(2)加std::setfill('0')。要注意setw只對下一個輸出有效,setfill則會一直保持。
寫法上的小建議: 我的答案用 seconds = seconds % 60; 把原本的秒數蓋掉了。這題因為已經先算完小時和分鐘,所以沒問題;但如果之後還要用到原本的總秒數就會出錯。另外用一個變數(例如 secs)存結果會比較安全。
(還沒寫)
#include<stdio.h>int main() { int seconds, hours, minutes; scanf("%d", &seconds);
hours = seconds / 3600; minutes = (seconds % 3600) / 60; seconds = seconds % 60;
printf("%d:%02d:%02d\n", hours, minutes, seconds); return 0;}C 或 C++ 皆可|CPU 時間上限 1 秒
給你一段以「秒」為單位的時間長度 n,把它換算成「時:分:秒」的格式輸出。
1 小時 = 60 分鐘,1 分鐘 = 60 秒。
一行,一個整數 n(0 ≤ n ≤ 1,000,000,000),單位是秒。
一行,格式是 H:MM:SS,三個部分用英文冒號 : 隔開:
H:小時數。不補零,也沒有上限(可能超過 24,例如 100 小時就印100)MM:分鐘數(0 到 59),一定印兩位數,不足兩位時前面補0SS:秒數(0 到 59),一樣印兩位數,不足兩位時前面補0
輸入:
3725輸出:
1:02:053725 秒 = 1 小時(3600 秒)+ 2 分鐘(120 秒)+ 5 秒。
輸入:
59輸出:
0:00:59- 兩個整數相除
/的結果還是整數,小數部分直接捨去:3725 / 3600是1 %取餘數:3725 % 3600是125- C:
printf("%02d", x)表示「至少印 2 個字元寬,不足的部分在前面補 0」 - C++:
#include <iomanip>,用std::setw(2)設定寬度、std::setfill('0')設定補什麼字元
提示 1:怎麼拆成時、分、秒?
先算小時:n / 3600。
剩下不到一小時的秒數是 n % 3600,再把它拆成分鐘(除以 60)和秒(對 60 取餘數)。
提示 2:%2d 和 %02d 差在哪裡?
printf("%2d", 5)印出5(前面補空白)printf("%02d", 5)印出05(前面補零)printf("%d", 5)印出5(不補)
小時不補零,分和秒要補零,所以三個部分的格式不一樣。
提示 3:C++ 的 setw 只管「下一個」輸出
std::setfill('0') 設定一次之後會一直有效,但 std::setw(2) 只對緊接在後面的那一個輸出有效,所以分和秒前面都要各寫一次 std::setw(2)。
std::cout << h << ':' << std::setfill('0') << std::setw(2) << m << ':' << std::setw(2) << ...