【发布时间】:2018-09-16 11:59:30
【问题描述】:
输入由一组按开始时间升序给出的任务组成,每个任务都有一个相关的持续时间。 第一行是任务数,例如
3
2 5
4 23
7 4
这意味着有 3 个任务。第一个从时间 2 开始,到 7 (2+5) 结束。第二个从 4 开始,到 27 结束。第三个从 7 开始,在 11 结束。 我们假设每个任务一旦准备好就开始,并且不需要等待处理器或其他任何东西释放。 这意味着我们可以跟踪活动任务的数量:
Time #tasks
0 - 2 0
2 - 4 1
4 - 11 2
11 - 27 1
我需要找到 2 个数字:
- 任何给定时间的最大活动任务数(在本例中为 2)和
- 此处计算的整个持续时间的平均活动任务数为:
[ 0*(2-0) + 1*(4-2) + 2*(11-4) + 1*(27-11) ] / 27
为此, 我首先使用以下代码找到了所有任务结束的时间:
#include "stdio.h"
#include "stdlib.h"
typedef struct
{
long int start;
int dur;
} task;
int main()
{
long int num_tasks, endtime;
long int maxtime = 0;
scanf("%ld",&num_tasks);
task *t = new task[num_tasks];
for (int i=0;i<num_tasks;i++)
{
scanf("%ld %d",&t[i].start,&t[i].dur);
endtime = t[i].start + t[i].dur;
if (endtime > maxtime)
maxtime = endtime;
}
printf("%ld\n",maxtime);
}
这可以使用作为堆实现的优先级队列来完成吗?
【问题讨论】:
-
这是 C 还是 C++?我看到你使用 C 头文件,但是 C++ 中的
new关键字。 -
这是 C++。文件格式为.cc。
-
试试这个 -- 把所有的时间,不管是开始时间还是结束时间,都放在一个数组里,按时间升序对数组进行排序。然后遍历数组,如果时间是开始时间,则将计数加 1,如果时间是结束时间,则从计数中减去 1。计数的最大值是活动任务的最大数量。诀窍在于,哪个任务开始或哪个结束都无关紧要,即使它是问题的一部分,那也是无关紧要的信息。您只需要知道 a 任务已经开始并且 a 任务已经结束。
-
当然可以使用优先队列来完成。但这不是最简单的解决方案,因此不应使用。最简单的解决方案将简单地对一组开始和结束时间进行排序,然后对其进行一次迭代以找到最大活动任务。这也会产生第一个开始时间和最后一个结束时间,因此是整个时间跨度。然后,您可以遍历所有任务以找到它们运行时间的总和并将其除以总时间跨度。排序是
O(n log n),其他步骤都是O(n)的琐碎循环。
标签: c++ heap priority-queue event-driven