CCF CSP Brush Question Record 22-201709-2 Public Key Box (Java)

Question number: 201709-2
Question name: Public key box
time limit: 1.0s
Memory limit: 256.0MB
Problem Description:

Problem Description

  There is a school where teachers share N classrooms. According to regulations, all keys must be placed in a public key box. Teachers cannot bring the keys home. Before each class, the teacher finds the key to the classroom where he is in the public key box to open the door, and then puts the key back in the key box after the class.
  There are a total of N hooks in the key box , arranged in a row from left to right, to hang N classroom keys. There is no fixed hanging position for a bunch of keys, but there are signs on the keys, so teachers will not confuse the keys.
  Every time the key is taken, the teachers will find the key they need and take it away, instead of moving other keys. Every time the key is returned, the teacher who returns the key will find the leftmost empty hook and hang the key on this hook. If more than one teacher returns the keys, they will return the keys in ascending order of the key number. If both the teacher returns the key and the teacher takes the key at the same time, the teachers will return all the keys before taking it out.
  At the beginning of today, the keys are placed in the key box in ascending order of numbers. There are K teachers who want to attend the class. Give each teacher the keys, the time to start the class and the length of the class. Assuming that the end of class is the time to return the keys, what is the order of the keys in the final key box?

Input format

  The first line of input contains two integers NK .
  In the next K lines, each line contains three integers wsc , which respectively represent the key number to be used by a teacher, the time to start the class, and the length of the class. There may be multiple teachers using the same key, but the time the teacher uses the key will not overlap.
  Ensure that the input data meets the input format, and you do not need to check the validity of the data.

Output format

  Output a line containing N integers, separated by a space between adjacent integers, indicating the number of the key hanging on each hook in turn.

Sample input

5 2
4 3 3
2 2 7

Sample output

1 4 3 2 5

Sample description

  The first teacher uses the key of classroom 4 from time 3 and uses 3 units of time, so the key is returned at time 6. The second teacher started using the key at time 2, using 7 units of time, so he returned the key at time 9.
  The key status after each key moment is as follows (X means empty):
  1X345 after time 2; 1X3X5
  after time 3; 143X5
  after time 6; and
  14325 after time 9.

Sample input

5 7
1 1 14
3 3 12
1 15 12
2 7 20
3 18 12
4 21 19
5 30 9

Sample output

1 2 3 5 4

Evaluation use case scale and conventions

  对于30%的评测用例,1 ≤ NK ≤ 10, 1 ≤ w ≤ N, 1 ≤ sc ≤ 30;
  对于60%的评测用例,1 ≤ NK ≤ 50,1 ≤ w ≤ N,1 ≤ s ≤ 300,1 ≤ c ≤ 50;
  对于所有评测用例,1 ≤ NK ≤ 1000,1 ≤ w ≤ N,1 ≤ s ≤ 10000,1 ≤ c ≤ 100。

 

这题没有满分,然后网上搜罗了大佬的想法思路,在这边记录一下:

程序一共分为3步:

 1.初始化钥匙的序列(从小到大排列), 初始化教师对象并且存入一个容器中, 还需要初始化一个计时器用于教师们存取钥匙.
 2.归还钥匙: 根据设置的计时器,判断当前是否有要归还钥匙的老师,如果有,那么将老师持有的钥匙序号存入一个容器中,如果有多个老师,则将容器内的钥匙号码排序,然后依次存入放置钥匙的容器内.
 3.取钥匙: 根据设置的计时器,判断是否有要借用钥匙的老师,如果有,则直接从钥匙序列中取走钥匙(即将对应钥匙号码置0)
 4.由于不存在同一时刻要使用同一把钥匙的情况(也不太符合实际情况),所以不用担心这点,另外为什么要先归还钥匙再借用钥匙? 看了代码后自己思考下吧

 

 

总的来说:

1.首先我们定义两个整数用于接收*钥匙数量N*和*教师数量K*, 同时声明一个整型的*时间计数器time*,初始设置为*1单位时间*,还需声明一个数组用于初始化钥匙序列.  
2.本题中,模拟实际情况,将教师实例化为对象, 将借钥匙和还钥匙写成方法, 所以需要一个容器存储这些教师对象,这里选用集合存储, 同时还需声明一个集合用于记录当前被借用的钥匙序号, 所以需要声明两个集合,而且要写一个Teacher类, 里面有w,s,c三个属性,用来记录要用的钥匙号,上课开始时间,上课持续时间,另外,我还添加了一个e属性,e=s+c,用来表示这个教师归还钥匙的时间,方便后面的计算.
3.编写归还钥匙的方法,这个方法需要接收几个参数
原理如下:
     首先清空上一次要归还的钥匙集合,为这一次存储要归还的钥匙做准备,然后判断这一时刻是否有老师要归还钥匙,如果没有,直接结束方法,如果有,那么先将要归还的钥匙序号存入这个集合,然后将这个集合排序,最后排查钥匙数组里面的空位,依次归还钥匙.
4.编写借用钥匙的方法,这个方法同样需要接收几个参数
原理如下:
    判断当前时间需要借用钥匙的老师,然后在钥匙数组中将对应的钥匙号码处置0即可.
5.最后,程序结束的条件是当前的时间大于最后一个老师归还钥匙的时间即可(这里写了一个方法用于比较时间).
6.由于本题的老师对象中有多个时间的判断点,而且各不干扰,所以算法实现起来比较方便.
 

 

 

import java.util.ArrayList;
import java.util.Scanner;

/*
 * 1.利用集合存入教师数据,初始化钥匙序列N, K:教师人数 时间记录器:time, 集合存储要归还的钥匙
 * 2.还钥匙:根据当前时间判断归还钥匙的老师,将钥匙序号存入集合,排序,再依次放回数组中
 * 3.取钥匙:根据当前时间,判断能使用钥匙的老师,执行取钥匙方法
 * 教师: w:钥匙号    s:开始上课    c:上课时间    e:s+c 结束时间
 */
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //存老师
        ArrayList<Teacher> arrt1 = new ArrayList<Teacher>();
        //存要归还的钥匙
        ArrayList<Integer> key = new ArrayList<Integer>();
        int time = 1;
        int N = sc.nextInt();
        int K = sc.nextInt();
        int[] arr = new int[N];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = i + 1;
        }
        for (int i = 1; i <= K; i++) {
            Teacher t = new Teacher(sc.nextInt(), sc.nextInt(), sc.nextInt());
            arrt1.add(t);
        }
        //结束条件是当前时间大于最后一个老师上完课的时间
        while(time <= maxTime(arrt1)){
            returnKey(time, arrt1, arr, key);
            borrowKey(time, arrt1, arr);
            time++;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }

    public static void returnKey(int time, ArrayList<Teacher> arrt1, int[] arr, ArrayList<Integer> key) {
        //清空放置要归还钥匙的集合
        key.clear();
        //判断这个时间是否有需要归还钥匙的老师
        for (int i = 0; i < arrt1.size(); i++) {
            if (arrt1.get(i).e == time) {
                key.add(arrt1.get(i).w);
            }
        }
        if (key.isEmpty()) {
            //没有钥匙则不归还
            return;
        } else {
            //将要归还的钥匙从大到小排序
            for (int i = 0; i < key.size() - 1; i++) {
                for (int j = 0; j < key.size() - 1 - i; j++) {
                    if (key.get(j) > key.get(j + 1)) {
                        int temp = key.get(j);
                        key.set(j, key.get(j + 1));
                        key.set(j + 1, temp);
                    }
                }
            }
            //归还钥匙
            for (int i = 0, j = 0; i < arr.length; i++) {
                if(arr[i] == 0){
                    arr[i] = key.get(j);
                    if(key.size()-1 == j){
                        break;
                    }else{
                        j++;
                    }
                }
            }
        }
    }

    public static void borrowKey(int time, ArrayList<Teacher> arrt1, int[] arr){
        for (int i = 0; i < arrt1.size(); i++) {
            //判断在当前时间能够使用钥匙的老师
            if(time == arrt1.get(i).s){
                //取走钥匙
                for (int j = 0; j < arr.length; j++) {
                    if(arrt1.get(i).w == arr[j]){
                        arr[j] = 0;
                        break;
                    }
                }
            }
        }
    }

    public static int maxTime(ArrayList<Teacher> arrt1){
        int temp = 0;
        for (int i = 0; i < arrt1.size(); i++) {
            if(arrt1.get(i).e > temp){
                temp = arrt1.get(i).e;
            }
        }
        return temp;
    }
}

class Teacher {
    int w;
    int s;
    int c;
    int e;

    public Teacher(int w, int s, int c) {
        this.w = w;
        this.s = s;
        this.c = c;
        this.e = this.s + this.c;
    }
}

转载自:https://blog.csdn.net/ZZ2013215/article/details/78561461

Guess you like

Origin blog.csdn.net/m0_37483148/article/details/108363010