ccf钥匙盒 java解法
我一开始是使用时间加1加1的遍历最后得到30分,后来发现代码可以循环更少的次数就是先把每次取钥匙和还钥匙的时间排序。
一开始使用一个二维数组存储取的钥匙,取的时间,归还的时间加上取的时间
//创建一个二维数组存储
int[][] timetable = new int[k][3];
for(int i=0;i<k;i++) {
timetable[i][0] = write.nextInt();
timetable[i][1] = write.nextInt();
timetable[i][2] = write.nextInt();
timetable[i][2] = timetable[i][1] + timetable[i][2];
}
然后创建一个数组来存储钥匙的排放情况
//创建一个数组存储钥匙排放情况
int[] keybox = new int[n];
for(int i=0;i<n;i++) {
keybox[i] = i+1;
}
然后通过循环取得最晚归还钥匙的时间
再建立一个数组用来存放每次归还和取钥匙的时间
//建立一个数组存储每次归还和取钥匙的时间用于遍历
int[] time = new int[2*k];
for(int i=0;i<k;i++) {
for(int j=1;j<3;j++) {
time[2*i+j-1] = timetable[i][j];
}
}
通过hash来对上面的数组进行去重排序
//对时间数组进行去重 排序
HashSet<Integer> hashSet = new HashSet<Integer>(); // 去重
for (int i = 0; i < time.length; i++){
hashSet.add(time[i]);
}
Set<Integer> set = new TreeSet(hashSet); // 利用TreeSet排序
Integer[] integers = set.toArray(new Integer[]{});
int[] time1 = new int[integers.length]; // 我们排序、去重后的结果数组
for (int i = 0; i < integers.length; i++){
time1[i] = integers[i].intValue();
}
最后通过对上面那个数组的循环来遍历并且取钥匙和还钥匙
取钥匙则将钥匙盒数组的对应位置置换为0,归还则置换为相应的钥匙编号
如果遇到同一时间归还的,则先将他们存储进一个队列,通过对列对钥匙编号进行排序,然后再归还,注意要先遍历归还,再取
//时间每次加进行遍历查询
while(time2<maxtime) {
time2 = time1[c++];
//归还钥匙
//创建列表存储可能会相同时间归还的钥匙
ArrayList list = new ArrayList<>();
for(int i=0;i<k;i++) {
if(timetable[i][2]==time2) {
list.add(timetable[i][0]);
}
}
//对列表进行排序
Collections.sort(list);
//按照列表顺序进行钥匙归还
for(int i=0;i<list.size();i++) {
for(int j=0;j<n;j++) {
if(keybox[j]==0) {
keybox[j]=(int) list.get(i);
break;
}
}
}
//拿钥匙
for(int i=0;i<k;i++) {
if(timetable[i][1]==time2) {
for(int j=0;j<n;j++) {
if(timetable[i][0]==keybox[j]) {
keybox[j] = 0;
}
}
}
}
}
最后输出钥匙盒数组,要按照要求的格式进行输出
最后附上全部代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class Main {
public static void main(String[] args) {
Scanner write = new Scanner(System.in);
int n = write.nextInt();
int k = write.nextInt();
//创建一个二维数组存储
int[][] timetable = new int[k][3];
for(int i=0;i<k;i++) {
timetable[i][0] = write.nextInt();
timetable[i][1] = write.nextInt();
timetable[i][2] = write.nextInt();
timetable[i][2] = timetable[i][1] + timetable[i][2];
}
//创建一个数组存储钥匙排放情况
int[] keybox = new int[n];
for(int i=0;i<n;i++) {
keybox[i] = i+1;
}
//找到最晚归还钥匙的时间
int maxtime = timetable[0][2];
for(int i=1;i<k;i++) {
if(timetable[i][2] > maxtime) {
maxtime = timetable[i][2];
}
}
//建立一个数组存储每次归还和取钥匙的时间用于遍历
int[] time = new int[2*k];
for(int i=0;i<k;i++) {
for(int j=1;j<3;j++) {
time[2*i+j-1] = timetable[i][j];
}
}
//对时间数组进行去重 排序
HashSet<Integer> hashSet = new HashSet<Integer>(); // 去重
for (int i = 0; i < time.length; i++){
hashSet.add(time[i]);
}
Set<Integer> set = new TreeSet(hashSet); // 利用TreeSet排序
Integer[] integers = set.toArray(new Integer[]{});
int[] time1 = new int[integers.length]; // 我们排序、去重后的结果数组
for (int i = 0; i < integers.length; i++){
time1[i] = integers[i].intValue();
}
int time2 = 0;
int c = 0;
//时间每次加进行遍历查询
while(time2<maxtime) {
time2 = time1[c++];
//归还钥匙
//创建列表存储可能会相同时间归还的钥匙
ArrayList list = new ArrayList<>();
for(int i=0;i<k;i++) {
if(timetable[i][2]==time2) {
list.add(timetable[i][0]);
}
}
//对列表进行排序
Collections.sort(list);
//按照列表顺序进行钥匙归还
for(int i=0;i<list.size();i++) {
for(int j=0;j<n;j++) {
if(keybox[j]==0) {
keybox[j]=(int) list.get(i);
break;
}
}
}
//拿钥匙
for(int i=0;i<k;i++) {
if(timetable[i][1]==time2) {
for(int j=0;j<n;j++) {
if(timetable[i][0]==keybox[j]) {
keybox[j] = 0;
}
}
}
}
}
//按照格式输出钥匙序列
for(int i=0;i<keybox.length-1;i++) {
System.out.print(keybox[i]+" ");
}
System.out.print(keybox[keybox.length-1]);
}
}