解题思路:
用优先队列模拟接还的过程,最开始使用两个队列分别维护待借的时间Q1,一个维护待还的时间Q2,但是超时了,其实自需要维护一个队列就可以了,定义一个类{flag标志是否已经借出,start开始时间,end结束的时间(题目的给出的是时长,需要用start+时长)},队列里面保持start或end最小,主要是优先队列里面的比较器的优先级的判断
顺带复习了一波优先队列
博客链接:http://www.cnblogs.com/tstd/p/5125949.html
import java.util.*;
/**
* @author Shixiaodong
* @date 2018/3/13 23:02
*/
public class Main {
static class take {
public boolean flag; //是否借出
public int room; //room教室编号
public int start; //开始时间
public int end; //结束时间
}
public static Queue<take> startList = new PriorityQueue<take>(new Comparator<take>() {
@Override
public int compare(take o1, take o2) {
if (o1.flag == o2.flag) { //标志为相同的情况下比较
if(o1.flag == false) { //都没借出的情况比较优先级
if (o1.start <= o2.start) { //时间小优先级高
return -1;
}
return 1;
} else { //都借出的情况比较优先级
if(o1.end == o2.end) {
if(o1.room < o2.room) { //room小的优先归还,优先级高
return -1;
}
return 1;
}
if(o1.end < o2.end) {
return -1;
}
return 1;
}
} else { //标志为不同的情况下比较
if (o1.flag == false) {
if(o1.start < o2.end) { //借的时间比还的时间早,优先级当然高
return -1;
}
if(o1.start == o2.end) { //借的时间和还的时间一样,根据题意优先还钥匙
return 1;
}
return 1;
} else {
if(o1.end <= o2.start) { //还的时间比借的早,优先级高
return -1;
}
return 1;
}
}
}
});
public static int roomNum; //房间号
public static int record; //记录数
public static int[] room = new int[1001]; //房间数组
public static void getKey(int needKey) { //取钥匙
for (int i = 1; i <= roomNum; i++) {
if(room[i] == needKey) {
room[i] = 0;
return;
}
}
}
public static void returnKey(int keyNum) { //归还钥匙
for (int i = 1; i <= roomNum ; i++) {
if(room[i] == 0) {
room[i] = keyNum;
return;
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String[] temp = scanner.nextLine().split(" ");
roomNum = Integer.parseInt(temp[0]);
record = Integer.parseInt(temp[1]);
for(int i = 1; i <= roomNum; i++) {
room[i] = i;
}
for(int i = 0; i < record; i++) {
temp = scanner.nextLine().split(" ");
take t = new take();
t.room = Integer.parseInt(temp[0]);
t.start = Integer.parseInt(temp[1]);
t.end = Integer.parseInt(temp[2]) + t.start;
t.flag = false;
startList.add(t);
}
take t1 = null;
do {
t1 = startList.poll();
if(t1.flag == false) {
getKey(t1.room);
t1.flag = true; //设置标记
startList.add(t1); //只有add后会触发重新排序
} else {
returnKey(t1.room);
}
} while (startList.size() != 0);
for (int i = 1; i < roomNum; i++) {
System.out.print(room[i] + " ");
}
System.out.println(room[roomNum]);
}
}