题目
去官网看
思路
大体思路写在了注释里面,开两个数组分别记录对应事务的开始时间和结束时间,进行排序,在每个时间点进行判断是否存在归还钥匙亦或者是取走钥匙的行为发生。
C++ 代码
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1001;
int n, k;
int n1 = 1;
int n2 = 1;
int x[maxn], p[maxn];
struct node
{
int id;
int time;
};
node t1[maxn], t2[maxn];
// 时间第一关键字 序号第二关键字
bool cmp(node a, node b)
{
if (a.time == b.time)
{
return a.id < b.id;
}
return a.time < b.time;
}
// 归还钥匙
void re(int id)
{
for (int i = 1; i <= n; ++i)
{
if (x[i] == 0)
{
// x表示1-n位置上放的是哪个钥匙
x[i] = id;
// p表示1-n号钥匙放在了哪个位置上
// 两者为映射关系
p[id] = i;
break;
}
}
}
int main()
{
cin >> n >> k;
for (int i = 1; i <= n; ++i)
{
x[i] = i;
p[i] = i;
}
for (int i = 1; i <= k; ++i)
{
int w, s, c;
cin >> w >> s >> c;
node r1 = { w,s };
node r2 = { w,s + c };
// t1保存id和开始时间
t1[i] = r1;
// t2保存id和结束时间
t2[i] = r2;
}
// 排序
sort(t1 + 1, t1 + 1 + k, cmp);
sort(t2 + 1, t2 + 1 + k, cmp);
// s为所有活动中最早开始的时间
int s = t1[1].time;
// e为所有活动中最后结束的时间
int e = t2[k].time;
for (int i = s; i <= e; ++i)
{
// 判断是否还有任务未结束且结束时刻为当前时刻
while ((n2 <= k) && (t2[n2].time == i))
{
// 还钥匙
re(t2[n2].id);
++n2;
}
// 判断是否还有任务未开始且开始时刻为当前时刻
while ((n1 <= k) && (t1[n1].time == i))
{
// 获取该钥匙所在的位置
int pos = p[t1[n1].id];
// 取走该钥匙
x[pos] = 0;
++n1;
}
}
for (int i = 1; i <= n; ++i)
{
cout << x[i] << " ";
}
cout << endl;
system("pause");
return 0;
}