CCF-201709-2-公共钥匙盒

还有几天就要考证了,把这题又刷了一遍,所以过来把旧代码替换了。
2018-12-6新添加python代码,太简洁了。

####思路:
这题让我们模拟老师们的存取钥匙的过程,输出最后钥匙的摆放位置。每个时间点有拿和放钥匙的操作,我们只需把每个时间点的拿和放操作存好就好办了。先弄一个时间表,表里存放时间点,在每个时间点里存放有哪些钥匙是拿的和放的。

####程序说明:
timetable是存放Moment类的对象数组,Moment类里面有getList和putList,用来存某个时刻需要拿和放的钥匙。类里还有拿和放的操作。

具体流程:
1.存好数据
2.遍历timetable,每个时刻先放钥匙再取钥匙
3.输出钥匙盒

import java.util.Collections;
import java.util.LinkedList;
import java.util.Scanner;

public class 公共钥匙盒练习 {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        int k = input.nextInt();
        int[] keyBox = new int[n];
        Moment[] timetable = new Moment[10200];//用来存放时刻的时间表

        //初始化钥匙盒
        for (int i = 0; i < n; i++)
            keyBox[i] = i + 1;

        //初始化对象数组timetable
        for (int i = 0; i < timetable.length; i++)
            timetable[i] = new Moment();

        //把每个时刻的存取操作存在对应的时刻中
        for (int i = 0; i < k; i++) {
            int key = input.nextInt(); //该老师要用的钥匙编号
            int start = input.nextInt(); //该老师上课开始时间
            int end = input.nextInt() + start; //下课时间
            //往对应时刻里存放要存取的钥匙
            timetable[start].getList.offer(key);
            timetable[end].putList.offer(key);
        }

        //遍历时间表,模拟存取操作
        for (Moment m : timetable) {
            //先放后取
            m.put(keyBox);
            m.get(keyBox);
        }

        //打印钥匙盒
        for (int key : keyBox)
            System.out.print(key + " ");
    }
}

//时刻类
class Moment {
    LinkedList<Integer> putList = new LinkedList<>();//某时刻要放的钥匙编号
    LinkedList<Integer> getList = new LinkedList<>();//某时刻要取的钥匙编号
    Moment() {}

    //某时刻的放操作
    void put(int[] keyBox) {
        if (!putList.isEmpty()) {
            Collections.sort(putList);
            for (int i = 0; i < keyBox.length; i++) {
                if (keyBox[i] == 0 && !putList.isEmpty())
                    keyBox[i] = putList.poll();
            }
        }
    }

    //某时刻的取操作
    void get(int[] keyBox) {
        while (!getList.isEmpty()) {
            int mK = getList.poll();
            for (int i = 0; i < keyBox.length; i++) {
                if (mK == keyBox[i])
                    keyBox[i] = 0;
            }
        }
    }
}

python代码

n, k = map(int, input().split())
# 钥匙盒
key_box = [v for v in range(1, n + 1)]
# 时刻列表,每个时刻包含一个还钥匙列表和一个拿钥匙列表
# 时间表最长长度为10101=10000 + 100 + 1
timeTable = [{'rtKeys': [], 'getKeys': []} for _ in range(10101)]

# 读取操作,给时间表添信息
for i in range(k):
    key, begin, l = map(int, input().split())
    end = begin + l
    timeTable[begin]['getKeys'].append(key)
    timeTable[end]['rtKeys'].append(key)

# 遍历时间表,每个时刻的钥匙先还再取,还的时候从左到右从小到大还
for time in timeTable:
    # 还钥匙
    for k in sorted(time['rtKeys']):
        for i in range(len(key_box)):
            if key_box[i] == 0:
                key_box[i] = k
                break
    # 拿钥匙
    for k in time['getKeys']:
        key_box[key_box.index(k)] = 0

[print(v, end=' ') for v in key_box]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值