QUST 2020級第三學期算法數據結構測試 Contest1029
T3
Problem Description
$m$ 名同學按順序從 $1$ 到 $m$ 編號, $k$ 號同學的飯盒容量為 $z_k$ 。先有1到 $m$ 號同學開始打飯。某名同學 $l$ 打完容量為 $z_l$ 的飯後,下一名排隊同學 $i$ 馬上接替 $l$ 同學的位置開始打飯。即 $l$ 同學第 $x$ 秒結束時完成打飯,則 $i$ 同學第 $x + 1$ 秒立刻開始打飯。若當前打飯人數 $n$ 小於 $m$ ,則只有 $n$ 個打飯窗口開放,其它 $n - m$ 個關閉。問所有同學都打完飯需要多少秒時間。
Inputs
輸入數據的第1行是2個整數 $m$ 和 $n$ $(1 \leq m \leq 10000, 1 \leq n \leq 100, 且 n \leq m)$ ,用一個空格隔開,分別表示打飯人數和打飯窗口個數。
第2行 $m$ 個整數 $z_1, z_2, …, z_m$ ,其中 $z_k$ 表示 $k$ 號同學的飯盒容量,且 $1 \leq z_k \leq 100$ 。
Outputs
輸出只有一行,為一個整數,表示所需的總時間。
Samples
Sample #1
Inputs (輸入)
1
25 3
4 4 1 2 1Outputs (輸出)
1
4
Explanations (解釋)
第1秒,3人打飯。第1秒結束時,1、2、3號同學每人的已打飯量為1,3號同學打飯完成,4號同學接替3號同學開始打飯。 第2秒,3人打飯。第2秒結束時,1、2號同學每人的已打飯量為2,4號同學的已打飯量為1。 第3秒,3人打飯。第3秒結束時,1、2號同學每人的已打飯量為3,4號同學的已打飯量為2。4號同學打飯完成,5號同學接替4號同學開始打飯。 第4秒,3人打飯。第4秒結束時,1、2號同學每人的已打飯量為4,5號同學的已打飯量為1。1、2、5號同學打飯完成,即所有人完成打飯。 總打飯時間為4秒。
Sample #2
Inputs (輸入)
1
210 3
6 3 3 10 3 1 5 2 2 7Outputs (輸出)
1
18
Analysis
1 |
|
筆者個人認為這道題是一道純粹的模擬題目,模擬題的噁心之處就在於你沒有任何一種固定的算法或數據結構模板能夠直接套在這個問題上。
越是複雜的模擬,越是無法三言兩語說清楚,只能一步一步慢慢講。
除了題目輸入的三種變量 $m, n, \{z_k\}_{k=1}^m$ 之外,我們額外設置一個變量task[]
來記錄並實時模擬每個窗口處理當前任務的時間進度,以及變量res[]
來記錄花費的總時間。
1 | int m, n, z[10001], task[101], res = 0; |
然後在程式起手時完成數據與變量的輸入
1 | int main(int argc, char *argv[]) { |
初始時刻,前n個人類會排滿n個窗口 (=・ω・=)
1 | for (int k = 0; k != n; ++k) |
另外,我們要用一個指針,在還在排隊的人們之中,記錄下一個辦理業務的人
1 | int nextone = n; |
接下來我們將逐時刻模擬各個窗口的進度,且每一時刻我們要檢查每個窗口的進度
1 | for (res = 0; ; ++res) { |
在上述三行中,我們定義了一個變量flag
,接下來會把其用於檢查任務完成情況 _(:з」∠)_
1 | if (task[k] > 0) |
根據上面所説,如若flag
不爲真,那麽就意味著模擬結束,可以在此時刻終結循環啦 XD
1 | } |
輸出結果並結束程式 _(≧∇≦」∠)_
1 | printf("%d\n", ++res); |
這道題主要就是,逐時刻逐窗口模擬,實時檢查完成情況。
Solution Program
1 |
|
Complexity Analysis
空間複雜度: 本題目水到不需要動態數組,因此空間複雜度為
O(1)
。時間複雜度: 最壞情況下,本解法的時間複雜度可能上升至 $O(m^2)$ 。