算法笔记练习 题解合集
题目
题目描述
读入任务调度序列,输出n个任务适合的一种调度方式。
输入
输入包含多组测试数据。
每组第一行输入一个整数n(n<100000),表示有n个任务。
接下来n行,每行第一个表示前序任务,括号中的任务为若干个后序任务,表示只有在前序任务完成的情况下,后序任务才能开始。若后序为NULL则表示无后继任务。
输出
输出调度方式,输出如果有多种适合的调度方式,请输出字典序最小的一种。
样例输入
4
Task0(Task1,Task2)
Task1(Task3)
Task2(NULL)
Task3(NULL)
样例输出
Task0 Task1 Task2 Task3
思路
- 把每一行行首的任务名称记录在
vector<string> tasks;
里面; - 把所有的优先级记录在
map<string, set<string> > priorTask;
里面,且这是个全局变量,方便排序。
例:若TaskA
是TaskB
的前序任务,那么priorTask[TaskA].insert(TaskB)
,就把TaskB
记录在了以TaskA
为值的那个映射的集合里面。考虑到一个任务可能是多个任务的前序任务,映射的值写成了set
; - 根据上一个步骤得到的优先级和字典序对
tasks
进行排序; - 输出排序结果。
代码
#include <iostream>
#include <string>
#include <cctype>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;
map<string, set<string> > priorTask;
bool cmp(const string& a, const string& b) {
return priorTask[a].count(b) ? true : a < b;
}
int main() {
int n, p, q;
string input, task;
vector<string> tasks;
cin >> n; getchar();
for (int i = 0; i < n; ++i) {
p = 0;
getline(cin, input);
while (isalnum(input[p]))
++p;
task = input.substr(0, p);
tasks.push_back(task);
do {
q = ++p;
while (isalnum(input[q]))
++q;
priorTask[task].insert(input.substr(p, q - p));
p = q;
} while (input[p] != ')');
}
sort(tasks.begin(), tasks.end(), cmp);
for (auto it = tasks.begin(); it != tasks.end(); ++it)
cout << *it << " ";
return 0;
}