问题描述
蒜头君设计了一个任务系统。这个系统是为了定时提醒蒜头君去完成一些事情。
系统大致如下,初始的时候,蒜头君可能会注册很多任务,每一个任务的注册如下:
Register Q_num Period |
---|
表示从系统启动开始,每过 Period 秒提醒蒜头君完成编号为 Qnum的任务。
你能计算出蒜头君最先被提醒的 k 个任务吗?
代码块:
package 基础数据结构;
import java.util.Collections;
import java.util.HashMap;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
/*
* 任务系统
*/
public class PriorityQueueDemo2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 任务数
int n = sc.nextInt();
// 输出的前k个任务
int k = sc.nextInt();
sc.nextLine();
// 创建优先队列(java中优先队列权值最小的元素在队首)
Queue<task> queue = new PriorityQueue<task>();
// 创建映射表,存储序号-时间映射(用于取出时间)
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
// 存入任务
for (int i = 1; i <= n; i++) {
// 注册指令
String s = sc.nextLine();
String[] ss = s.split(" ");
// 序号(时间相同情况下,小号优先)
int num = Integer.parseInt(ss[1]);
// 时间(时间短的优先)
int time = Integer.parseInt(ss[2]);
// 序号入队
queue.offer(new task(num, time));
// 序号-时间一一映射
map.put(num, time);
}
while (k > 0) {
// 取出队首元素(由优先队列性质,肯定是权值最小的)
task t = queue.poll();
// 直接输出序号
System.out.println(t.getNum());
// 加上间隔时间
t.setTime(t.getTime() + map.get(t.getNum()));
// 再次入队(入队后自动排序)
//java的优先队列是基于最小二叉堆实现的,排序的时间复杂度为O(nlogn))
queue.offer(t);
k--;
}
}
}
//构建task对象(实现Comparable接口,从而可以进行不同权值的比较)
class task implements Comparable<task> {
int num;
int time;
public task(int num, int time) {
this.num = num;
this.time = time;
}
public void setTime(int time) {
this.time = time;
}
public void setNum(int num) {
this.num = num;
}
public int getTime() {
return time;
}
public int getNum() {
return num;
}
@Override
public int compareTo(task t) {
// 先比较时间,时间小的优先级高(1表示优先级更低,-1表示优先级更高,0表示优先级相同)
if (time > t.getTime()) {
return 1;
}
if (time < t.getTime()) {
return -1;
}
// 时间相同的情况下,序号小的优先级高
else {
if (num < t.getNum()) {
return -1;
}
return 1;
}
}
}