产品经理(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序号、提出时间、优先等级和所需时间。
所有输入数据范围为 [1, 3000]
输出P行,分别表示每个idea实现的时间点。
生产者消费者问题的状态模拟:我们需要将输入的任务根据提出时间加入生产者队列(使用优先队列,按照提出时间先后排序)。随着时间K的改变,判断消费者(程序员)的状态和任务状态,将任务加到待办事项队列中(此队列也使用优先队列,根据题意对设计自定义排序),具体看待发注释。
import java.util.*; public class Main { //创建Idea类 static class Idea { int id;//记录任务序号,于PM编号无关 int time;//记录任务提出时间 int order;//记录任务优先级 int spendTime;//记录任务花费时间 int finish;//记录任务完成时间,初始化默认为-1 public Idea(int id,int time,int order,int spendTime) { this.id = id; this.time = time; this.order = order; this.spendTime = spendTime; this.finish = -1; } } public static void main (String []args){ Scanner scanner = new Scanner(System.in); String[] str = scanner.nextLine().split(" "); int N = Integer.parseInt(str[0]),M = Integer.parseInt(str[1]),P = Integer.parseInt(str[2]); //记录程序员的任务剩余工作时间 int[] programer = new int [M]; //记录每个任务 HashMap<Integer, Idea> map = new HashMap<>(); //生产线 //按照提出时间排序 PriorityQueue<Idea> createQ = new PriorityQueue<>(Comparator.comparingInt(o -> o.time)); //待完成任务 //按照优先级order->花费时间spendTime->提出时间time排序 PriorityQueue<Idea> taskQ = new PriorityQueue<>(new Comparator<Idea>() { @Override public int compare(Idea o1, Idea o2){ if(o1.order > o2.order){ return 1; }else if(o1.order < o2.order){ return -1; }else{ if(o1.spendTime > o2.spendTime){ return 1; }else if(o1.spendTime < o2.spendTime){ return -1; }else{ if(o1.time > o2.time){ return 1; }else if(o1.time < o2.time){ return -1; }else{ return 0; } } } } }); //初始化生产者队列 for(int i = 0; i < P; i++) { String[] temp = scanner.nextLine().split(" "); Idea idea = new Idea(i,Integer.parseInt(temp[1]),Integer.parseInt(temp[2]),Integer.parseInt(temp[3])); map.put(i, idea); createQ.add(idea); } //两个Queue都是空时,停止 int k = 0; while ((!taskQ.isEmpty()) || (!createQ.isEmpty())) { while ((!createQ.isEmpty()) && createQ.peek().time == k) { taskQ.offer(createQ.poll()); } int indexProgramer = 0;//遍历每一个程序员 while (indexProgramer < programer.length) { if(programer[indexProgramer] > 0){ programer[indexProgramer]--; //程序员干活啦 indexProgramer++; }else{//这个程序员空闲 if(taskQ.isEmpty()){ indexProgramer++; }else{//有任务做了 Idea idea = taskQ.poll(); idea.finish = k + idea.spendTime;//计算完成时间 programer[indexProgramer] = idea.spendTime;//程序员需要消耗的时间 } } } k++;//时间增加 } for(int i = 0; i < P; i++){ System.out.println(map.get(i).finish); } } }