CCF201709 公共鑰匙盒(JAVA)
問題描述: | 問題描述 有一個學校的老師共用N個教室,按照規定,所有的鑰匙都必須放在公共鑰匙盒裡,老師不能帶鑰匙回家。每次老師上課前,都從公共鑰匙盒裡找到自己上課的教室的鑰匙去開門,上完課後,再將鑰匙放回到鑰匙盒中。 輸入格式 輸入的第一行包含兩個整數N, K。 輸出格式 輸出一行,包含N個整數,相鄰整數間用一個空格分隔,依次表示每個掛鉤上掛的鑰匙編號。 樣例輸入 5 2 樣例輸出 1 4 3 2 5 樣例說明 第一位老師從時刻3開始使用4號教室的鑰匙,使用3單位時間,所以在時刻6還鑰匙。第二位老師從時刻2開始使用鑰匙,使用7單位時間,所以在時刻9還鑰匙。 樣例輸入 5 7 樣例輸出 1 2 3 5 4 評測用例規模與約定 對於30%的評測用例,1 ≤ N, K ≤ 10, 1 ≤ w ≤ N, 1 ≤ s, c ≤ 30;
思路:建立時間軸,將事件標記在時間軸上,同時利用好TreeMap與TreeSet的有序性來存放資料將大大簡化操作 |
package publicKeyBox;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Map;
import java.util.Scanner;
public class Main {
static Map<Integer, TreeMap<Integer, TreeSet<Integer>>> timeBar = new TreeMap<>();// 時間軸
@SuppressWarnings("resource")
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();// 掛鉤數
int k = sc.nextInt();// 上課老師數
int[] keyBox = new int[N];// 鑰匙盒
// 將所有老師的借走與歸還鑰匙的事件,包括時間點與對應教室的鑰匙記錄在時間軸上
for (int i = 0; i < k; i++) {
int key = sc.nextInt();// 鑰匙
int bor = sc.nextInt();// 借走時間
int ret = bor + sc.nextInt();// 歸還時間
createEvent(ret);
timeBar.get(ret).get(0).add(key);// 登記歸還資訊進入時間軸
createEvent(bor);
timeBar.get(bor).get(1).add(key);// 登記借走資訊進入時間軸
}
for (int i = 0; i < N; i++)
// 初始化鑰匙盒
keyBox[i] = i + 1;
for (TreeMap<Integer, TreeSet<Integer>> a : timeBar.values()) {
int c = 0;// 記錄空位定址起點序號
for (int b : a.get(0))// 先歸還
{
for (; c < N; c++)// 找空位
{
if (keyBox[c] == 0) {
keyBox[c] = b;
break;
}
}
}
for (int d : a.get(1))// 後取出
{
for (int e = 0; e < N; e++) {
if (keyBox[e] == d) {
keyBox[e] = 0;// 空位記0
break;
}
}
}
}
for (int result : keyBox) {
System.out.print(result + " ");// 輸出keyBox
}
}
public static void createEvent(int t) {
if (!timeBar.containsKey(t))// 時間軸上時間點不存在
{
TreeMap<Integer, TreeSet<Integer>> baR = new TreeMap<>();// 該時間點存放鑰匙總事件集合
TreeSet<Integer> bor = new TreeSet<>();// 借鑰匙事件集合
TreeSet<Integer> ret = new TreeSet<>();// 還鑰匙事件集合
baR.put(0, ret);
baR.put(1, bor);
timeBar.put(t, baR);// 將事件標記在時間軸
}
}
}