题目内容
给出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 keyfor(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 keyfor(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;
}