CCF 201709-2 公共钥匙盒 (100分)

本文介绍了一个基于时间轴的钥匙借用系统模拟算法。该算法利用STL的set建立时间轴,通过二维数组borrow和restore记录钥匙的借用和归还,同时使用map记录每把钥匙的位置,最终输出挂架上钥匙的状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目内容
给出N把钥匙挂在挂架上,编号从左到右为1~N。然后给出K个老师的钥匙使用信息w, s, c,分别表示一位老师要使用的钥匙编号、开始上课的时间和上课的时长。还钥匙时每次都先放在挂架最左边的空位。借钥匙时就直接取下钥匙。如果同时有老师借和还,就先按钥匙编号从小到大还完后再借钥匙。老师使用钥匙的时间不会重叠。

样例输入

5 2
4 3 3
2 2 7

样例输出

1 4 3 2 5

样例输入

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

思路
在输入数据时就建立时间轴,可以使用STL的set来建立,set自动从小到大排序;然后根据建立好的时间轴里,每个时间点都有动作发生,要么借,要么还。所以使用两个二维数组,borrow和restore数组,一维成员就是时间轴的点,二维成员就是要进行操作的钥匙。
注意,restore数组里面的钥匙要按编号从小到大排序。borrow就不用。
再使用一个map来记录每把钥匙的当前位置,供后续操作使用。然后再开始时建立一个挂架数组hanger来模拟当前挂架情况。
执行时以时间轴进行循环,循环结束后输出当前挂架hanger的钥匙情况即可。

C++代码

#include <iostream>
#include <vector>
#include <map>
#include <set>
using namespace std;
int main(){
 int numberOfKey,numberOfTeacher;
 int keyNum,start,duration,end;
 cin >> numberOfKey >> numberOfTeacher;
 int hanger[numberOfKey + 1];
 map<int,int> key;
 set<int> time;
 set<int> emptyPos;
 vector<vector<int> > borrow(10101);
 vector<set<int> > restore(10101);
 for(int i = 1; i <= numberOfKey; i++){
  key[i] = i; 
  hanger[i] = i;
 }
 for(int i = 0; i < numberOfTeacher; i++){
  cin >> keyNum >> start >> duration;
  end = start + duration;
  time.insert(start);
  time.insert(end);
  borrow[start].push_back(keyNum);
  restore[end].insert(keyNum);
 }
 for(auto it = time.begin(); it != time.end(); it++){
  if(restore[*it].size() != 0){// restore key
   for(auto kt = restore[*it].begin();
    kt != restore[*it].end(); kt++){
     hanger[*emptyPos.begin()] = *kt;
     key[*kt] = *emptyPos.begin();
     emptyPos.erase(*emptyPos.begin());
    }
  }
  if(borrow[*it].size() != 0)// borrow key
   for(int i = 0; i < borrow[*it].size(); i++)
     emptyPos.insert(key[borrow[*it][i]]);
 }
 for(int i = 1; i <= numberOfKey; i++){
  if(i - 1)
   cout << ' ';
  cout << hanger[i];
 }
 return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值