3377 [mz]接水問題2
時間限制: 1 s
空間限制: 64000 kb
題目等級 : 鑽石 diamond
題解 檢視執行結果
題目描述 description
學校裡有乙個水房,水房裡一共裝有m個龍頭可供同學們開啟水,每個龍頭每秒鐘的供水量相等,均為1。
現在有n名同學準備接水,他們的初始接水順序已經確定。將這些同學按接水順序從 1到n編號,i號同學的接水量為wi。接水開始時,1到m號同學各佔乙個水龍頭,並同時開啟水龍頭接水。當其中某名同學j完成其接水量要求wj後,下一名排隊等候接水的同學k馬上接替j同學的位置開始接水。這個換人的過程是瞬間完成的,且沒有任何水的浪費。即j同學第x秒結束時完成接水,則k同學第x+1秒立刻開始接水。若當前接水人數n』不足m,則只有n』個龍頭供水,其它m-n』個龍頭關閉。
現在給出n名同學的接水量,按照上述接水規則,問所有同學都接完水需要多少秒。
特別地,同學們在打水前排好了隊,接水所用時間更長的先接。
(ps:出題人本來想設計乙個貪心的題目,然後發現用貪心做有反例,只能強改題目,在此宣告道歉。不要在意樣例解釋。)
輸入描述 input description
第 1 行2 個整數 n 和 m,用乙個空格隔開,分別表示接水人數和龍頭個數。
第 2 行 n 個整數 w1、w2、„„、wn,每兩個整數之間用乙個空格隔開,wi表示 i 號同學的接水量。
輸出描述 output description
輸出只有一行,1 個整數,表示接水所需的總時間。
樣例輸入 sample input
5 34 4 1 2 1
樣例輸出 sample output
4思路:
模擬性質的堆
先排序,從大到小
然後把前m個丟進堆裡
每次取出最小的,加上正在排隊的最大的,丟回去
隨手維護max
輸出max
小技巧:
隨手維護max,可以省去最後一步把堆裡的數都丟出來取最大;
stl的優先佇列是 priority_queue< *** > (可以用搜狗輸入法打哦)
重定義小根堆 priority_queue《型別,vector《型別》,greater《型別》 > (注意最後乙個空格)
//優先佇列版
#include
#include
#include
#include
#include
using
namespace
std;
int n,m,num[1000050],tot,maxx;
priority_queue,greater > q;
bool cmp(int a,int b)
int main()
while(tot<=n)
printf("%d",maxx);
return
0;}
//手打堆版
#include
#include
#include
#include
using
namespace
std;
const
int maxn=1000050ll;
int n,m,num[maxn],d[maxn],maxx;
void inswap(int a,int b)
void inpop()
else
}return ;
}void inpush(int x)
else
}return ;
}int main()
for(int i=1;i<=m;i++)
maxx=max(maxx,d[i]);
printf("%d",maxx);
return
0;
}
codevs 3377 Mz 接水問題2
學校裡有乙個水房,水房裡一共裝有m個龍頭可供同學們開啟水,每個龍頭每秒鐘的供水量相等,均為1。現在有n名同學準備接水,他們的初始接水順序已經確定。將這些同學按接水順序從 1到n編號,i號同學的接水量為wi。接水開始時,1到m號同學各佔乙個水龍頭,並同時開啟水龍頭接水。當其中某名同學j完成其接水量要求...
codevs 3377 Mz 接水問題2
學校裡有乙個水房,水房裡一共裝有m個龍頭可供同學們開啟水,每個龍頭每秒鐘的供水量相等,均為1。現在有n名同學準備接水,他們的初始接水順序已經確定。將這些同學按接水順序從 1到n編號,i號同學的接水量為wi。接水開始時,1到m號同學各佔乙個水龍頭,並同時開啟水龍頭接水。當其中某名同學j完成其接水量要求...
P3377 左偏樹,模板)
題意 如題,一開始有n個小根堆,每個堆包含且僅包含乙個數。接下來需要支援兩種操作 操作1 1 x y 將第x個數和第y個數所在的小根堆合併 若第x或第y個數已經被刪除或第x和第y個數在用乙個堆內,則無視此操作 操作2 2 x 輸出第x個數所在的堆最小數,並將其刪除 若第x個數已經被刪除,則輸出 1並...