PAT甲級刷題實錄 1014

2022-05-25 07:48:08 字數 1604 閱讀 5706

這題需要用到佇列,而且不止一條。首先是每個等待視窗各需要一條,另外在黃線外的等待顧客需要一條。c++提供了現成了現成的佇列型別,只要引用標頭檔案queue即可。

演算法基本執行過程是:在輸入顧客等待時間時依次填滿每條佇列,超出佇列容量的,即編號大於n*m+1的顧客,則push進黃線外的等待佇列中。當有視窗有顧客處理完畢後,則將該顧客pop出佇列,同時從黃線外等待佇列中pop出乙個顧客並push進該視窗對應的佇列中。最後直到黃線外等待隊列為空為止。當然,光靠這個基本執行過程去寫**肯定是不行的,因為還需要在演算法執行過程中計算每個顧客處理完成的時間,同時還需要判斷何時進出佇列。這也是本道題最難的兩個地方。因為c++沒有提供處理時間相關的型別,所以直接用時刻來計算非常麻煩,我們可以轉變一種思路,即將時間轉換為從8點開始經過的分鐘數,最後輸出結果的時候轉換為hh:mm形式的時刻即可,這樣就大大方便了計算。對於解決兩個難點問題,我的思路是:記錄每個佇列隊首元素處理完畢後的時間(從8點開始的經過的分鐘數)htime,這個時間也就是黃線外等待佇列中的元素能夠進入該佇列的時間。另外記錄每個佇列隊尾元素處理完畢後的時間(從8點開始的經過的分鐘數)ttime,這個時間用於計算新進入佇列的顧客開始處理的時間以及最終處理完畢的時間。在排程時,每次按佇列下標依次找htime最小的佇列,將該佇列中的隊首元素彈出,在隊尾插入從黃線外等待佇列彈出的元素,同時更新htime和ttime,並記錄新進入佇列顧客的開始時間和結束時間。這種方法能夠符合題目如果兩個佇列都有一樣多的空位,找編號更小的佇列,假設出現多條佇列的隊首元素同時處理完畢,即多條佇列都有空位,因為我們是按下標從小到大找的,只要把判斷條件改為小於就能夠找到編號最小的佇列,而且下一次迴圈還是能找到編號最小的。對於題目另乙個要求,即找最短的佇列插入,這個情況實際上只會出現在最初初始化的階段,初始化之後的執行過程中一旦一條佇列有空位馬上就會有顧客填入,即所有佇列基本都是處於滿員狀態,最多出現乙個空位,不存在多個空位的佇列,因此無需考慮長短問題。

另外我在做這題的時候一開始有乙個理解有誤的地方,我以為只要顧客的結束時間晚於17:00那就不能處理了,但實際上是開始時間不能晚於17:00,如果在17:00點前開始了,哪怕最後結束的時間超過了17:00,也得給他處理完畢。這也是真實工作生活中的情況。

#include #include #include using namespace std;

struct cinfo

;int main()

else //佇列全部已滿

}while (outwait.size() != 0) //在黃線外等待的不為空

}lines[num].pop();

cinfo c = outwait.front();

outwait.pop();

lines[num].push(c);

htime[num] += lines[num].front().ptime;

customers[c.cnum].begintime = ttime[num];

ttime[num] += c.ptime;

customers[c.cnum].endtime = ttime[num];

} for (int i = 0; i < q; i++) }

return 0;

}

PAT甲級刷題實錄 1008

這題應該是到目前為止最簡單的一道題,評測系統的通過率統計也達到了驚人的0.59。我們需要定義以下用於計算的變數 currentfloor 當前所在的樓層,初始值為0 nextfloor 接下來要前往的樓層,數值通過讀取輸入來確定 totaltime 經過的總時間。因為這題思路實在太簡單了,我也不用自...

PAT甲級刷題實錄 1005

這題相對比較簡單,就是逐個讀入數字然後加起來,算出來的總和從最高位開始逐位用英文輸出。需要注意的是,題中所給的數字是連在一起的,沒有用空格隔開,而如果直接用cin會把一整串數字都讀進去,這不是我們想要的。逐個字元讀入需要用到的是cin.get 方法。不過這樣讀進來的是char型別,如果用int輸出相...

PAT甲級刷題

給定兩個字串s1和s2,刪除s1中在s2 現過的字元設定flag陣列,初始化為0。遍歷s2並將其字元轉化為ascii碼值,並在flag陣列中相應位置值標記為1,表示它出現過。再遍歷s1,若對應字元ascii碼值在flag陣列中相應位置值標記為0,則輸出。就是hash的思想,時間複雜度o len s1...