Try   HackMD

TOI 2021下學期 新手組題目解析

3月

1. 時區(Zone)

題目分析

  • 時間系統跟現實的異同
    • 時、分、秒數量關係不變。換句話說,
      1
      hr =
      60
      mins,
      1
      mins =
      60
      secs
    • 一天還是
      24
      個時區
    • 一個時區變成
      1.5
      小時,因此一天有
      36
      小時,也就是
      36×60=2160
      分鐘
  • 加減時區
    T
    會影響到
    • 秒數
      S
      :不變
    • 分鐘數
      M
      :雙數個時區不變,單數個時區會加減
      30
      。結果可能大於60或小於
      0
      ,因此必須是除以
      60
      的餘數。另外,超過
      60
      則多一小時,小於
      0
      則少一小時。
    • 小時數
      H
      :有可能跨過換日線。超過36會多一天,小於0會少一天,因此必須是除以
      36
      的餘數。

解題技巧說明

  • 調整
    T
    :往前
    n
    個時區,相當於往後
    (24n)
    個時區。因此,時區可以統一往前移,亦即把
    T
    統一為正數。
  • 小時全部化為分鐘:分鐘數依時區加減完畢後,再除以
    60
    ,商數即
    H
    ,餘數即
    M

注意事項

  • 負數除法結果。e.g.
    (5)÷2
    • 數學運算結果:商為
      3
      ,餘數為
      1
    • 程式運算結果:商為
      2
      ,餘數為
      1
  • 輸出格式。
    • H
      M
      S
      均為正數
    • M
      S
      若小於10,需補0,湊滿兩位數
    • H
      不用動

測資發想

題目測資只有部分狀況,請考量各種極端狀況,自己生測資來測試。

  • 各種排列組合:
    • T
      為正、
      T
      為負
    • M>30
      的時候加單數時區、
      M<30
      的時候減單數時區
    • 結果大於
      36:00:00
      、小於
      0:00:00

範例程式碼

調整T
#include <iostream> using namespace std; int main() { int h, m, s, t; cin >> h >> m >> s >> t; if (t < 0) { t = t + 24; } m += t * 90 % 60; h += t * 90 / 60; // 因為t必為正,僅需考慮m超過60、h超過36的狀況來調整m, h if (m > 60) { m = m - 60; h = h + 1; } if (h >= 36) { h = h - 36; } cout << h << ":"; if(m<10) cout<<"0"; cout << m << ":"; if(s<10) cout<<"0"; cout << s << "\n"; return 0; }
化小時為分鐘
#include <iostream> using namespace std; int main() { int h, m, s, t; cin >> h >> m >> s >> t; int msum = h*60 + m + t*90; if (msum < 0) msum += 2160; m = msum % 60; h = (msum/60) % 36; cout << h << ":"; if(m<10) cout<<"0"; cout << m << ":"; if(s<10) cout<<"0"; cout << s << "\n"; }
調整T、化小時為分鐘
#include <iostream> using namespace std; int main() { int h, m, s, t; cin >> h >> m >> s >> t; if(t < 0) t = t+24; int msum = h*60 + m + t*90; m = msum % 60; h = (msum/60) % 36; cout << h << ":"; if(m<10) cout<<"0"; cout << m << ":"; if(s<10) cout<<"0"; cout << s << "\n"; }

2. 幸運7(Lucky 7)

題目分析

  • 輸入:以0為終點,不確定會有幾個數字,已知最多有10個數字
  • 比較:一次抽兩個數字出來比較,分成四種情況,再做對應的處理:
    • 兩數皆可被7整除:取70的餘數較大的比較大
    • 第一數可被7整除:第一數較大
    • 第二數可被7整除:第二數較大
    • 兩數皆無法被7整除:取 77 的餘數較小的比較大

解題技巧說明

  • 使用for迴圈或while迴圈進行輸入
  • 使用多重選擇結構進行判斷
  • 資料結構
    • 不使用資料結構:輸入一個新的數字,就要馬上與前一數比較,找出最大值,重複直到最後一個數字。
    • 使用資料結構(如:陣列):因無法預估長度,可預先開固定大小的陣列。

注意事項

  • 使用if-else if-else時,注意先後順序
  • 如不使用資料結構,在輸入下一個數字之前,就要立刻進行比較
  • 如果使用陣列,陣列大小應該開11。之所以是11,是因為剛好有10個數字的話,會存到最後一個0。
  • 如果使用陣列,全部開始比較之前,需要設一暫存變數存「目前為止的最大值」,而暫存變數的值建議設為0或第0個數字的值。

測資發想

  • 各種排列組合:
    • 四種情況
    • 兩個數字,或兩個以上的數字
    • 最大數出現在第一個、中間、最後一個

範例程式碼

使用while,不使用迴圈
#include <iostream> using namespace std; int main() { int n; int max; cin >> n; max = 0; while(n != 0){ if (max == 0) max = n; else{ if(n%7 == 0 && max%7 != 0) max = n; else if(n%7 == 0 && max%7 == 0){ if(n%70 > max%70) max = n; }else if(n%7 != 0 && max%7 != 0){ if(n%77 < max%77) max = n; }else{ ; } } cin >> n; } cout << max << endl; return 0; }
使用for-loop搭配break/continue指令,陣列開最大
#include <iostream> using namespace std; // 已知全部數字加上0,不會超過11個數字 #define N 11 int main() { int n, max = 0; for(int i = 0; i < N; i++){ cin >> n; if (n == 0) break; if (max == 0){ max = n; continue; } if(n%7 == 0 && max%7 != 0) max = n; else if(n%7 == 0 && max%7 == 0){ if(n%70 > max%70) max = n; }else if(n%7 != 0 && max%7 != 0){ if(n%77 < max%77) max = n; }else{ ;// 展示用,這裡什麼都不用做,最大值不變 } } cout << max << endl; return 0; }

3. 蟲蟲危機(Insect)

題目分析

  • 所有螞蟻的數量要比蚱蜢多:比較前面兩個輸入即可得知
  • 螞蟻的總身高比蚱蜢高:用兩個變數和迴圈,分別連加求得螞蟻、蚱蜢總身高。

注意事項

  • 輸入一個數字後,可以馬上累加起來,和計算機的原理很像,因此不需要分成兩個迴圈去處理。

測資發想

  • 各種排列組合:
    • 螞蟻的數量大於、等於、小於蚱蜢的數量
    • 螞蟻的總身高大於、等於、小於蚱蜢總身高

範例程式碼

#include <iostream> using namespace std; int main() { int m, n, msum = 0, nsum = 0; cin >> m >> n; int mm[m], nn[n]; for(int i=0; i<m; i++){ cin >> mm[i]; msum += mm[i]; } for(int i=0; i<n; i++){ cin >> nn[i]; nsum += nn[i]; } if(m<=n) cout << "No\n"; else if(msum<=nsum) cout << "No\n"; else cout << "Yes\n"; return 0; }