CCF 公共钥匙盒 java实现 100分代码

原题:**
问题描述
  有一个学校的老师共用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]+" ");
		}
		
	}
	
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值