题目的核心点:因为输入是一口气把所有idea都输入进来了,所以在程序中需要为每个程序员维护一个当前时间,程序员在所有idea中挑idea的时候,只有当程序员的当前时间大于idea的提出时间才可能会处理这个idea。接着那如何从多个可能会处理的idea中挑出一个呢?根据题目意思是,先在PM层面根据规则为每个PM挑一个,然后程序员再根据规则从中挑一个。
实现的核心点:
1. 因为有多个程序员,每个程序员的当前时间都不一样,所以我们每次在处理idea的时候,需要挑出当前时间最小的程序员,先让这个程序员去挑idea,每次挑出当前时间最小的程序员可以用小根堆实现。
2. 如果本次的程序员一个idea都没有挑出来,那么就表示当前所有的idea的提出时间都大于这个程序员的当前时间,这个时候我们需要将这个程序员的当前时间向前推进1。
题外话:感觉本地重点考察的不是单纯的数据结构与算法,而是面向对象的思想。以下的代码实现为了精简同时保持好的可读性,对于类的属性没有使用getter/setter。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt(); //PM数
        int m = sc.nextInt(); //programmer数
        int p = sc.nextInt(); //idea数
        ArrayList<Idea> ideas = new ArrayList<>(p); //需求池
        for (int i = 0; i < p; i++) ideas.add(new Idea(i, sc.nextInt(), sc.nextInt(), sc.nextInt(), sc.nextInt()));
        sc.close();
        PriorityQueue<Programmer> programmers = new PriorityQueue<>(m, Comparator.comparingInt(o -> o.nowTime)); //小根堆,找到最先有空的程序员
        for (int i = 0; i < m; i++) programmers.add(new Programmer(1)); //每个程序员的初始时间都是1
        int[] res = new int[p]; //这个数组保存的就是最后的结果,因为要按需求输入的顺序输出每个需求的完成时间,所以在idea里面保留了一个seq,最后会将需求完成的时间按seq写入数组
        while (!ideas.isEmpty()) { //处理需求池中的需求
            Programmer programmer = programmers.remove();
            int seq = programmer.handle(ideas, N);
            if (seq != -1) res[seq] = programmer.nowTime;
            programmers.add(programmer);
        }
        for (int i : res) System.out.println(i);
    }
}


class Idea {
    int seq;
    int pmNo;
    int createTime;
    int priority;
    int duration;

    public Idea(int seq, int pmNo, int createTime, int priority, int duration) {
        this.seq = seq;
        this.pmNo = pmNo;
        this.createTime = createTime;
        this.priority = priority;
        this.duration = duration;
    }
}

class Programmer {
    int nowTime;

    public Programmer(int nowTime) {
        this.nowTime = nowTime;
    }

    private Idea selectIdea(List<Idea> ideas, int pms) {
        Idea[] tpIdeaOfPms = new Idea[pms]; //top priority idea of PMs,每个PM最想完成的需求
        for (Idea idea : ideas) {//挑出每个PM最想完成的需求
            if (this.nowTime < idea.createTime) continue; //这个需求提出的时间大于当前程序员所处的时间,所以现在不予考虑,直接pass
            if (tpIdeaOfPms[idea.pmNo - 1] == null) {
                tpIdeaOfPms[idea.pmNo - 1] = idea;
                continue;
            }
            if (idea.priority < tpIdeaOfPms[idea.pmNo - 1].priority) {
                continue;
            }
            if (idea.priority > tpIdeaOfPms[idea.pmNo - 1].priority) {
                tpIdeaOfPms[idea.pmNo - 1] = idea;
                continue;
            }
            if (idea.duration > tpIdeaOfPms[idea.pmNo - 1].duration) {
                continue;
            }
            if (idea.duration < tpIdeaOfPms[idea.pmNo - 1].duration) {
                tpIdeaOfPms[idea.pmNo - 1] = idea;
                continue;
            }
            if (idea.createTime > tpIdeaOfPms[idea.pmNo - 1].createTime) {
                continue;
            }
            if (idea.createTime < tpIdeaOfPms[idea.pmNo - 1].createTime) {
                tpIdeaOfPms[idea.pmNo - 1] = idea;
                continue;
            }
        }
        Idea selectedIdea = null; //该程序员最终选择的需求
        for (Idea idea : tpIdeaOfPms) { //从每个PM最想完成的需求中挑出一个
            if (idea == null) continue;
            if (selectedIdea == null) selectedIdea = idea;
            if (idea.duration < selectedIdea.duration) {
                selectedIdea = idea;
            } else if (idea.duration == selectedIdea.duration && idea.pmNo < selectedIdea.pmNo) {
                selectedIdea = idea;
            }
        }
        return selectedIdea;
    }

    public int handle(List<Idea> ideas, int pms) {
        Idea selectedIdea = this.selectIdea(ideas, pms);
        if (selectedIdea != null) { //处理pm的需求
            nowTime += selectedIdea.duration;
            ideas.remove(selectedIdea);
            return selectedIdea.seq;
        } else { //当前时间pm没有提需求,时间继续向前
            nowTime += 1;
            return -1;
        }
    }

}