1. 程式人生 > >今日頭條筆試題--2018(3) 【 優先隊列 】

今日頭條筆試題--2018(3) 【 優先隊列 】

pre operator 程序 兩個 分別是 strong 條件 ide priority

時間限制:1秒

空間限制:81920K

產品經理(PM)有很多好的idea,而這些idea需要程序員實現。現在有N個PM,在某個時間會想出一個 idea,每個 idea 有提出時間、所需時間和優先等級。對於一個PM來說,最想實現的idea首先考慮優先等級高的,相同的情況下優先所需時間最小的,還相同的情況下選擇最早想出的,沒有 PM 會在同一時刻提出兩個 idea。

同時有M個程序員,每個程序員空閑的時候就會查看每個PM尚未執行並且最想完成的一個idea,然後從中挑選出所需時間最小的一個idea獨立實現,如果所需時間相同則選擇PM序號最小的。直到完成了idea才會重復上述操作。如果有多個同時處於空閑狀態的程序員,那麽他們會依次進行查看idea的操作。

求每個idea實現的時間。

輸入第一行三個數N、M、P,分別表示有N個PM,M個程序員,P個idea。隨後有P行,每行有4個數字,分別是PM序號、提出時間、優先等級和所需時間。輸出P行,分別表示每個idea實現的時間點。


輸入描述:
輸入第一行三個數N、M、P,分別表示有N個PM,M個程序員,P個idea。隨後有P行,每行有4個數字,分別是PM序號、提出時間、優先等級和所需時間。全部數據範圍 [1, 3000]。


輸出描述:
輸出P行,分別表示每個idea實現的時間點。

輸入例子1:
2 2 5
1 1 1 2
1 2 1 1
1 3 2 2
2 1 1 2
2 3 5 5

輸出例子1:
3
4
5
3
9

想法:
1 采用時間順序來模擬 對於每一個時間點 如果某個pm產生idea則進入該pm的優先隊列
2 對於所有pm的優先事件建立一個優先隊列2
3 判斷每個程序員是否忙碌,空閑時開始處理idea(隊列2彈出頂部,同樣該idea的pm優先隊列也彈出,並將之後的優先事件重新彈入隊列2)
錯誤點:
無法計算_end終止時間。註意循環跳出的時間
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=3007;
 4 struct
node { 5 int num; 6 int id; 7 int s,l,p; 8 }; 9 struct cmp1 { 10 bool operator() (const node& a,const node& b) { 11 if (a.p==b.p&&a.l==b.l) 12 return a.s>b.s; 13 else if (a.p==b.p) 14 return a.l>b.l; 15 else return a.p<b.p; 16 } 17 }; 18 struct cmp2 { 19 bool operator() (const node& a,const node& b) { 20 if (a.l==b.l) 21 return a.id>b.id; 22 return a.l>b.l; 23 } 24 }; 25 bool cmp (node a,node b) { 26 return a.s<b.s; 27 } 28 priority_queue <node, vector <node>,cmp1> q[N]; 29 priority_queue <node, vector <node>,cmp2> qs; 30 bool isok[N]; int e_t[N]; 31 node idea[N]; int ans[N]; 32 int _s; 33 int n,m,k; 34 int main () 35 { 36 _s=0x3f3f3f3f; 37 scanf ("%d %d %d",&n,&m,&k); 38 for (int i=1;i<=k;i++) { 39 idea[i].num=i; 40 scanf ("%d %d %d %d",&idea[i].id,&idea[i].s,&idea[i].p,&idea[i].l); 41 _s=min (_s,idea[i].s); 42 } 43 sort (idea+1,idea+1+k,cmp); 44 for (int i=1;i<=m;i++) isok[i]=1; 45 int j=1; 46 for (int i=_s; ;i++) { 47 while (j<=k&&idea[j].s<=i) { 48 q[idea[j].id].push(idea[j]); 49 j++; 50 } 51 while (!qs.empty()) qs.pop(); 52 for (int t=1;t<=n;t++) { 53 if (!q[t].empty()) 54 qs.push(q[t].top()); 55 } 56 for (int t=1;t<=m&&!qs.empty();t++) { 57 if (!isok[t]&&e_t[t]<=i) isok[t]=1; 58 // if (!isok[t]&&e_t[t]==i) isok[t]=1; 錯誤點1 59 if (isok[t]) { 60 // 核心代碼 61 node tmp=qs.top(); qs.pop(); 62 isok[t]=0; e_t[t]=i+tmp.l; 63 ans[tmp.num]=e_t[t]; 64 q[tmp.id].pop(); 65 if (!q[tmp.id].empty()) 66 qs.push(q[tmp.id].top()); 67 } 68 } 69 if (j>k&&qs.empty()) break; // 錯誤點2 註意終止條件 70 } 71 for (int i=1;i<=k;i++) 72 printf("%d\n",ans[i]); 73 return 0; 74 }

今日頭條筆試題--2018(3) 【 優先隊列 】