今日頭條筆試題,任務排程問題
阿新 • • 發佈:2018-12-31
產品經理(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
輸出
3 4 5 3 9
java AC程式碼如下:
import java.util.*; public class Main{ private static Scanner sc = new Scanner(System.in); static class IdeaTask { int pmSeq; int raiseTime; int prio; int timeCost; int endTime; public IdeaTask(int pmSeq, int raiseTime, int prio, int timeCost) { this.pmSeq = pmSeq; this.raiseTime = raiseTime; this.prio = prio; this.timeCost = timeCost; } } static class PM { PriorityQueue<IdeaTask> pq = new PriorityQueue<>(Comparator.comparingInt(x -> x.raiseTime)); //給定程式設計師開始工作的時間,找到這個PM最想完成的任務 IdeaTask mostDesiredTask(int startTime) { PriorityQueue<IdeaTask> pq2 = new PriorityQueue<>((x, y) -> { if (x.prio != y.prio) return y.prio - x.prio; else { if (x.timeCost != y.timeCost) return x.timeCost - y.timeCost; else return x.raiseTime - y.raiseTime; } }); while (pq.peek() != null && pq.peek().raiseTime <= startTime) { pq2.offer(pq.poll()); } IdeaTask mostDesiredTask = (pq2.isEmpty()) ? pq.poll() : pq2.poll(); while (!pq2.isEmpty()) { pq.offer(pq2.poll()); } return mostDesiredTask; } } static class Programmer { int nextWorkTime;//下次可以工作的時間 public Programmer(int nextWorkTime) { this.nextWorkTime = nextWorkTime; } } //從多個PM 最想要完成的Idea中,選其中的一個PM想要完成的idea private static IdeaTask selectTask(PM[] pms, int workTime) { PriorityQueue<IdeaTask> pq = new PriorityQueue<>((x, y) -> { if (x.raiseTime == y.raiseTime || (x.raiseTime <= workTime && y.raiseTime <= workTime)) { if (x.timeCost != y.timeCost) return x.timeCost - y.timeCost; else return x.pmSeq - y.pmSeq; } if (x.raiseTime > workTime && y.raiseTime > workTime) return x.raiseTime - y.raiseTime; if (x.raiseTime > workTime) return 1; if (y.raiseTime > workTime) return -1; return 0; }); for (int i = 1; i < pms.length; i++) { PM pm = pms[i]; IdeaTask desiredTask = pm.mostDesiredTask(workTime); if (desiredTask != null) pq.offer(desiredTask); } IdeaTask task = pq.poll(); while (!pq.isEmpty()) { IdeaTask tmp = pq.poll(); pms[tmp.pmSeq].pq.offer(tmp); } return task; } private static List<IdeaTask> getTasks(int taskNum) { List<IdeaTask> tasks = new LinkedList<>(); while (taskNum-- > 0) { tasks.add(new IdeaTask(sc.nextInt(), sc.nextInt(), sc.nextInt(), sc.nextInt())); } return tasks; } private static PM[] initPM(int n, List<IdeaTask> tasks) { PM[] pms = new PM[n + 1]; for (int i = 1; i <= n; i++) pms[i] = new PM(); for (IdeaTask task : tasks) { pms[task.pmSeq].pq.offer(task); } return pms; } public static void main(String[] args) { int n = sc.nextInt(), m = sc.nextInt(), p = sc.nextInt(); List<IdeaTask> tasks = getTasks(p); PM[] pms = initPM(n, tasks); PriorityQueue<Programmer> losersPq = new PriorityQueue<>(Comparator.comparingInt(x -> x.nextWorkTime)); for (int i = 0; i < m; i++) losersPq.offer(new Programmer(0)); while (true) { Programmer loser = losersPq.poll(); IdeaTask task = selectTask(pms, loser.nextWorkTime); if (task == null) break; task.endTime = Integer.max(task.raiseTime, loser.nextWorkTime) + task.timeCost; loser.nextWorkTime = task.endTime; losersPq.offer(loser); } for (IdeaTask task : tasks) { System.out.println(task.endTime); } } }