接水問題
題目
題目描述
學校裡有一個水房,水房裡一共裝有mmm個龍頭可供同學們開啟水,每個龍頭每秒鐘的供水量相等,均為1 11。
現在有n n n名同學準備接水,他們的初始接水順序已經確定。將這些同學按接水順序從 111到n n n編號,ii i號同學的接水量為 wiw_iwi。接水開始時,11 1到m mm 號同學各佔一個水龍頭,並同時開啟水龍頭接水。當其中某名同學j j j完成其接水量要求wj w_jwj後,下一名排隊等候接水的同學 kkk馬上接替 jjj 同學的位置開始接水。這個換人的過程是瞬間完成的,且沒有任何水的浪費。即jjj 同學第 xxx 秒結束時完成接水,則k kk 同學第 x+1x+1x+1 秒立刻開始接水。若當前接水人數 nnn’不足 mmm,則只有 nnn’個龍頭供水,其它 m−nm-nm−n’個龍頭關閉。
現在給出 nnn 名同學的接水量,按照上述接水規則,問所有同學都接完水需要多少秒。
輸入格式
第 111 行2 22 個整數 nnn 和 mmm,用一個空格隔開,分別表示接水人數和龍頭個數。
第 222 行 nnn 個整數w1,w2,…,wn w_1,w_2,…,w_nw1,w2,…,wn,每兩個整數之間用一個空格隔開,wiw_iwi表示i i i號同學的接水量。
輸出格式
111 個整數,表示接水所需的總時間。
輸入輸出樣例
5 3 4 4 1 2 1
4
8 4 23 71 87 32 70 93 80 76
163
說明/提示
【輸入輸出樣例 1 說明】
第 111 秒,33 3人接水。第 11 1秒結束時,1,2,31,2,3 1,2,3號同學每人的已接水量為 1,31,3 1,3號同學接完水,44 4號同學接替 333 號同學開始接水。
第 222 秒,33 3人接水。第2 22 秒結束時,1,21,2 1,2號同學每人的已接水量為 2,42,4 2,4號同學的已接水量為1 11。
第 333 秒,33 3人接水。第3 33 秒結束時,1,21,21,2 號同學每人的已接水量為 3,43,43,4 號同學的已接水量為 2。444 號同學接完水,555 號同學接替4 4 4號同學開始接水。
第4 44 秒,33 3人接水。第 44 4秒結束時,1,21,21,2 號同學每人的已接水量為 4,54,5 4,5號同學的已接水量為1 11。1,2,51,2,51,2,5 號同學接完水,即所有人完成接水的總接水時間為 444 秒。
【資料範圍】
1≤n≤10000,1≤m≤1001≤n≤10000,1≤m≤1001≤n≤10000,1≤m≤100 且m≤n m≤nm≤n;
1≤wi≤1001≤w_i≤1001≤wi≤100。
實現
這題乍一看會用模擬來做,一秒一秒得模擬,而這種方法實在太慢,有一個好辦法,那就是把正在使用水龍頭的剩餘最少的剩餘水量作為每一次模擬的時間,而非一秒一秒模擬。
具體思路是首先輸入,將前 m m m個賦值到水龍頭( s l t slt slt)的結構體陣列中,排序。接下來while迴圈,當所有人都開始接水時結束,while迴圈內 t i m e 1 time1 time1負責計算時間總和,每次加上剩餘最少的那個的水量, j i a n jian jian負責記錄那個人的剩餘水量(如果不加後面就不對了,原變數會被覆蓋)。while迴圈中for迴圈,將每個水量都減去 j i a n jian jian,if語句負責將沒有剩餘,也就是接好的人替換到下一個, n o w now now負責記錄下一個等待加水的人。while迴圈最後,排序。while迴圈結束,意味著所有人都在接水或已經接好水,此時,只需加上在加水的人中剩餘最多的水量即可。
說幹就幹,很快就可以寫出如下程式碼:
#include <bits/stdc++.h>
using namespace std;
int n,m;
int w[10005];
typedef struct node{
int water;
int number;
}node;
node slt[105];
int now=0;
int time1 = 0;
int jian;
bool cmp(node a,node b){
return a.water < b.water;
}
int main(){
cin >> n >> m;
for(int i = 0; i < n; i++){
cin >> w[i];
}
for(int i = 0; i < m; i++){
slt[i].water = w[i];
slt[i].number = i;
}
now = m;
sort(slt,slt+m,cmp);
while (now<=n){
time1+=slt[0].water;
jian = slt[0].water;
for(int i = 0; i < m; i++){
slt[i].water -= jian;
if(slt[i].water<=0){
slt[i].water=w[now];
slt[i].number=now;
now++;
}
}
sort(slt,slt+m,cmp);
}
sort(slt,slt+m,cmp);
time1 += slt[m-1].water;
cout << time1;
return 0;
}
主要講一下幾個坑點:
- while迴圈裡的條件
- while迴圈中 t i m e 1 time1 time1累加的位置
- 最後的加法不能忘。
相關文章
- P3242 接水果 題解
- 南沙C++信奧賽陳老師解一本通題 1950:【10NOIP普及組】接水問題C++
- P1223 排隊接水
- 洛谷P1223 排隊接水
- 問題 C: 百雞問題
- 【問題】Nacos 使用問題整理
- 什麼是P問題、NP問題和NPC問題
- 博基計劃(3)---P問題、NP問題、NPC問題、NP-hard問題
- [轉載]什麼是P問題、NP問題和NPC問題
- 【問題記錄】—.NetCore 編譯問題NetCore編譯
- Java服務.問題排查.問題復現Java
- 約瑟夫問題(丟手絹問題)
- 問題 F: 開燈問題(第二講)
- 提問題比解決問題更重要
- [開發問題]React-native問題集React
- 面試反問問題面試
- csrf問題
- 回溯問題
- LCS 問題
- 429問題
- 今日問題
- ABA 問題
- 【Git】問題Git
- MySQL 問題MySql
- pycharm問題PyCharm
- JS問題JS
- 倒水問題
- 有問題
- LeetCode問題LeetCode
- this指向問題
- UIImageJPEGRepresentation 問題UI
- clang 問題
- 火星商店問題 題解
- 遇到的編碼問題、時區問題整理
- 約瑟夫環問題 猴子選大王問題
- 完成20個問題後不敢發問題了
- 無題號 分配問題 題解
- 轉賬問題是屬於業務問題還是屬於技術問題?