• 头条笔试——调度问题


    链接: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();
        }
    }
  • 相关阅读:
    django.db.utils.OperationalError: (1071, 'Specified key was too long; max key length is 767 bytes');
    mysql的utf8与utf8mb4 异同;utf8mb4_unicode_ci 与 utf8mb4_general_ci 如何选择
    /etc/skel 目录作用
    react组件引用时的default常见错误
    Java效率工具之Lombok
    Java问题定位之如何借助线程堆栈进行问题分析
    Java线程堆栈分析
    Java问题定位之Java线程堆栈分析
    Java项目性能瓶颈分析及定位(八)——Java线程堆栈分析(五)
    SpringMVC的各种参数绑定方式
  • 原文地址:https://www.cnblogs.com/lshao/p/9590481.html
Copyright © 2020-2023  润新知