原题:**
问题描述
有一个学校的老师共用N个教室,按照规定,所有的钥匙都必须放在公共钥匙盒里,老师不能带钥匙回家。每次老师上课前,都从公共钥匙盒里找到自己上课的教室的钥匙去开门,上完课后,再将钥匙放回到钥匙盒中。
钥匙盒一共有N个挂钩,从左到右排成一排,用来挂N个教室的钥匙。一串钥匙没有固定的悬挂位置,但钥匙上有标识,所以老师们不会弄混钥匙。
每次取钥匙的时候,老师们都会找到自己所需要的钥匙将其取走,而不会移动其他钥匙。每次还钥匙的时候,还钥匙的老师会找到最左边的空的挂钩,将钥匙挂在这个挂钩上。如果有多位老师还钥匙,则他们按钥匙编号从小到大的顺序还。如果同一时刻既有老师还钥匙又有老师取钥匙,则老师们会先将钥匙全还回去再取出。
今天开始的时候钥匙是按编号从小到大的顺序放在钥匙盒里的。有K位老师要上课,给出每位老师所需要的钥匙、开始上课的时间和上课的时长,假设下课时间就是还钥匙时间,请问最终钥匙盒里面钥匙的顺序是怎样的?
输入格式
输入的第一行包含两个整数N, K。
接下来K行,每行三个整数w, s, c,分别表示一位老师要使用的钥匙编号、开始上课的时间和上课的时长。可能有多位老师使用同一把钥匙,但是老师使用钥匙的时间不会重叠。
保证输入数据满足输入格式,你不用检查数据合法性。
输出格式
输出一行,包含N个整数,相邻整数间用一个空格分隔,依次表示每个挂钩上挂的钥匙编号。
样例输入
5 2
4 3 3
2 2 7
样例输出
1 4 3 2 5
样例说明
第一位老师从时刻3开始使用4号教室的钥匙,使用3单位时间,所以在时刻6还钥匙。第二位老师从时刻2开始使用钥匙,使用7单位时间,所以在时刻9还钥匙。
每个关键时刻后的钥匙状态如下(X表示空):
时刻2后为1X345;
时刻3后为1X3X5;
时刻6后为143X5;
时刻9后为14325。
样例输入
5 7
1 1 14
3 3 12
1 15 12
2 7 20
3 18 12
4 21 19
5 30 9
样例输出
1 2 3 5 4
**
分析一下自己的思路:刚开始拿到题懵逼了一下,没啥好的想法,后来干脆想直接做,首先,肯定要维护一个数组,代表各个钥匙放的位置,board[n],
由于题目已经给定开始时间点和时长,我们可以算出结束时间点,对此,我用了两个map结构,
其中两个map的key分别是 开始时间点和结束时间点,value代表的是钥匙,也就是这个时间点该还或者该借的钥匙,这里要注意一下,由于在同一个时间点,可以还不止一把钥匙,也可以借不止一把钥匙,所有value的类型我用了ArrayList来封装在同一时间点要借或者要还的钥匙,还有要注意的一点是:老师取钥匙的时候取走该钥匙锁对应的抽屉为空,这里用board[index] = 0 来标记,我们需要知道该钥匙对应的抽屉是几号,对此,我又用一个map来保存钥匙和抽屉的对应关系,key值为钥匙号,value值为抽屉号,每次还钥匙,更新钥匙和抽屉的对应关系
先上代码吧(有点长,其实思路清晰了也不难)
package ccf第二题;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class PublicKeyboard {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int keyNum = in.nextInt();
int getKeyNum = in.nextInt();
int [] board = new int[keyNum+1];
//初始化
for (int i = 0; i < board.length; i++) {
board[i] = i;
}
board[0] = -1;
Map<Integer, ArrayList<Integer>> start = new HashMap<>();
Map<Integer,ArrayList<Integer>> end = new HashMap<>();
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < keyNum; i++) {
map.put(i+1, i+1); //钥匙号 桌子号
}
for (int i = 0; i < getKeyNum; i++) {
int keyIndex = in.nextInt();
int btm = in.nextInt();
int lasttime = in.nextInt();
int etm = btm+lasttime;
if(start.containsKey(btm)){
start.get(btm).add(keyIndex);
}else{
ArrayList<Integer> tmsta = new ArrayList<>();
tmsta.add(keyIndex);
start.put(btm, tmsta);
}
if(end.containsKey(etm)){
end.get(etm).add(keyIndex);
continue;
}
ArrayList<Integer> tmpt = new ArrayList<>();
tmpt.add(keyIndex);
end.put(etm, tmpt);
}
Object[] startSet = start.keySet().toArray();
Object[] endSet = end.keySet().toArray();
Arrays.sort(startSet);
Arrays.sort(endSet);
int i = 0,j = 0;
while(i<startSet.length && j<endSet.length){
int st = (int) startSet[i]; //借书时间
int et = (int)endSet[j]; // 还书时间
if(st < et){ //取钥匙
ArrayList<Integer> keys = start.get(st);
Object[] tmpt = keys.toArray();
Arrays.sort(tmpt);
for (int k = 0; k < tmpt.length; k++) {
board[map.get(tmpt[k])] = 0;
}
i++;
}
if(st > et){ //还钥匙
ArrayList<Integer> keys = end.get(et);
Object[] tmpt = keys.toArray();
Arrays.sort(tmpt);
int m = 0;
for (int k = 1; k < board.length; k++) {
if(m == tmpt.length)
break;
if(board[k] == 0){
board[k] = (int)tmpt[m];
map.put((int)tmpt[m],k );
m++;
}
}
j++;
}
if(st == et){ //这个时刻又还又取
ArrayList<Integer> keys = end.get(et);
Object[] tmpt = keys.toArray();
Arrays.sort(tmpt);
int m = 0;
for (int k = 1; k < board.length; k++) {
if(m == tmpt.length)
break;
if(board[k] == 0){
board[k] = (int)tmpt[m];
map.put((int)tmpt[m],k );
m++;
}
}
j++;
ArrayList<Integer> keys1 = start.get(st);
Object[] tmpt1 = keys1.toArray();
Arrays.sort(tmpt1);
for (int k = 0; k < tmpt1.length; k++) {
board[map.get(tmpt1[k])] = 0;
}
i++;
}
}
while(j<endSet.length){ //还
int et = (int)endSet[j];
ArrayList<Integer> keys = end.get(et);
Object[] tmpt = keys.toArray();
Arrays.sort(tmpt);
int m = 0;
for (int k = 1; k < board.length; k++) {
if(m == tmpt.length)
break;
if(board[k] == 0){
board[k] = (int)tmpt[m];
map.put((int)tmpt[m],k );
m++;
}
}
j++;
}
in.close();
for (int k = 1; k < board.length; k++) {
if(k == board.length-1){
System.out.print(board[k]);
break;
}
System.out.print(board[k]+" ");
}
}
}