今日头条笔试题--2018 优先队列
Posted xidian-mao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了今日头条笔试题--2018 优先队列 相关的知识,希望对你有一定的参考价值。
时间限制: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 ",ans[i]); 73 return 0; 74 }
以上是关于今日头条笔试题--2018 优先队列 的主要内容,如果未能解决你的问题,请参考以下文章
2018今日头条春招的一道笔试题 —— 通过改变枚举的变量进行枚举优化