头条笔试——调度问题

链接:https://www.nowcoder.com/questionTerminal/f76b7bc64e554edaa53d8e0d84f921c5
来源:牛客网

产品经理(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

AC通过代码
//用程序员的下次开始时间作为时间戳,用堆维护,每次取下次时间最小的,选择任务前先将上次检查点到提交时间<=当前时间的idea入每个PM相应的待执行队列(优先级队列)
//然后从每个PM的队列中取时间最短的
//很多ac 30%的问题在于,当程序员完成手头工作,PM队列中还有待执行任务的情况
//对于这种情况,我的做法是如果每个PM队列都为空,检查是否还有未入队列的idea,如果有,从中选提交时间最小的,并从这个时间开始工作,将未入队的入队,程序员选择任务
//上一步中,如果一个程序员触发了时间跳跃(即程序员的空闲时间),那么必须更新其他尚未跳跃的程序员的下次工作时间,做法就是和他选到的工作比较,如果他选到的工作的提交时间
//比他工作时间大,说明他需要更新,更新为选到的工作的提交时间即可
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {

    static class Idea implements Comparable<Idea>{
        int tm;
        int cost;
        int pr;
        int done;
        
        public Idea(int tm,int cost,int pr) {
            super();
            this.tm = tm;
            this.pr = pr;
            this.cost = cost;
        }

        @Override
        public int compareTo(Idea o) {
            // TODO Auto-generated method stub
            //优先级高,时间小,提出早
            int a;
            if(pr!=o.pr) 
                a=pr-o.pr;
            else if(cost!=o.cost)
                a=o.cost-cost;
            else a=o.tm-tm;
            return -a;
        }
    }
    
    static class Coder implements Comparable<Coder>{
        int id;
        int nextWorkTime;
        public Coder(int id, int nextWorkTime) {
            super();
            this.id = id;
            this.nextWorkTime = nextWorkTime;
        }
        @Override
        public int compareTo(Coder o) {
            // TODO Auto-generated method stub
            return -1*(o.nextWorkTime-nextWorkTime);
        }
    }
    int np,nm,ni;
    ArrayList<Idea>[] data;
    PriorityQueue<Idea>[] needDo;
    int[] lastcheckedIndex;
    PriorityQueue<Coder> coder;
    ArrayList<Idea> input=new ArrayList<>();
    int init() {
        int sttime=Integer.MAX_VALUE;
        Scanner is=new Scanner(System.in);
        np=is.nextInt();
        nm=is.nextInt();
        ni=is.nextInt();
        
        needDo=new PriorityQueue[np];
        lastcheckedIndex=new int[np];
        Arrays.fill(lastcheckedIndex, -1);
        data=new ArrayList[np];
        for(int i=0;i<np;i++) {
            data[i]=new ArrayList<Idea>();
            needDo[i]=new PriorityQueue<Idea>();
        }
        for(int i=0;i<ni;i++) {
            int ipm=is.nextInt();
            int itm=is.nextInt();
            int ipr=is.nextInt();
            int ict=is.nextInt();
            sttime=Math.min(itm, sttime);
            Idea idea=new Idea(itm, ict, ipr);
            data[ipm-1].add(idea);
            input.add(idea);
        }
        coder=new PriorityQueue<>();
        for(int i=0;i<nm;i++) {
            coder.add(new Coder(i+1,sttime));
        }
        
        is.close();
        for(ArrayList<Idea> arr:data)
            Collections.sort(arr,new Comparator<Idea>() {
                @Override
                public int compare(Idea o1, Idea o2) {
                    // TODO Auto-generated method stub
                    return o1.tm-o2.tm;
                }
            });
        
        
        return sttime;
    }
    
    
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Main test=new Main();
        int curtime=test.init();
        while(true) {
            Coder freeCoder=test.coder.poll();
            curtime=freeCoder.nextWorkTime;
            test.enNeedDO(curtime);
            Idea todo=test.getTodo();
            if(todo==null) {
                int jumptime=Integer.MAX_VALUE;
                boolean done=true;
                for(int i=0;i<test.lastcheckedIndex.length;i++) {
                    int j=test.lastcheckedIndex[i]+1;
                    if(j<test.data[i].size()) {
                        done=false;
                        jumptime=Math.min(jumptime, test.data[i].get(j).tm);
                    }
                }
                if(done)break;
                curtime=jumptime;
                test.enNeedDO(curtime);
                todo=test.getTodo();
            }
            if(todo.tm>curtime) curtime=todo.tm;
            todo.done=todo.cost+curtime;
            freeCoder.nextWorkTime=curtime+todo.cost;
            test.coder.add(freeCoder);
        }
            for(Idea idea:test.input)
                System.out.println(idea.done);
    }
    
    void enNeedDO(int curtime) {
        for(int i=0;i<data.length;i++) {
            int j=lastcheckedIndex[i]+1;
            while(j<data[i].size()&&data[i].get(j).tm<=curtime) {
                needDo[i].add(data[i].get(j));
                lastcheckedIndex[i]=j++;
            }
        }
    }
    
    Idea getTodo() {
        int costmin=Integer.MAX_VALUE;
        int costminPM=-1;
        for(int i=0;i<needDo.length;i++) {
            if(needDo[i].peek()!=null&&needDo[i].peek().cost<costmin) {
                costmin=needDo[i].peek().cost;
                costminPM=i;
            }
        }
        if(costminPM==-1) return null;
        return needDo[costminPM].poll();
    }
}
原文地址:https://www.cnblogs.com/lshao/p/9590481.html