题目描述
读入任务调度序列,输出n个任务适合的一种调度方式。
输入
输入包含多组测试数据。
每组第一行输入一个整数n(n<100000),表示有n个任务。
接下来n行,每行第一个表示前序任务,括号中的任务为若干个后序任务,表示只有在前序任务完成的情况下,后序任务才能开始。若后序为NULL则表示无后继任务。
输出
输出调度方式,输出如果有多种适合的调度方式,请输出字典序最小的一种。
样例输入 Copy
4
Task0(Task1,Task2)
Task1(Task3)
Task2(NULL)
Task3(NULL)
样例输出 Copy
Task0 Task1 Task2 Task3
解决策略:
1.这道题目我们需要一个结构体类型的优先队列,和一个映射map
2. 思路:可以在结构体中重载运算符 < 对队列中的结构体变量进行排序,处理后的队列输出即可,
3. 先弄出完整的带重载运算符函数的结构体来:
struct myTask{
string name;
int priority;
friend bool operator <(const myTask &t1,const myTask &t2)
{
if(t1.priority==t2.priority) return t1.name>t2.name;
else return t1.priority>t2.priority;
//重载了小于号的功能,如果两个结构体变量的优先级相同就按名字字典序从小到大排
//这样优先队列 的堆顶就是指定的任务名了
}
};
- 然后写出处理函数,判断输入的任务后面是否还有任务,如果有任务就把后面每一个任务对应的map 映射自增(使他们的优先级变大)。最后把当前任务的优先级从map中获取出来,把对应的结构体压入队列,
- 这样处理后,队列排成了按照优先级从小到大排列
code::
#include <iostream>
#include <string>
#include <queue>
#include <map>
using namespace std;
struct myTask{
string name;
int priority;
friend bool operator <(const myTask &t1,const myTask &t2)
{
if(t1.priority==t2.priority) return t1.name>t2.name;
else return t1.priority>t2.priority;
}
};
map<string,int> mp;
priority_queue<myTask> q;
void myfun(string &str)
{
myTask mytask;
mytask.name=str.substr(0,5);
if(str[6]!='N')
{
int index=5;
while(str[index]!=')')
{
index++;
mp[str.substr(index,5)]++;
index+=5;
}
}
mytask.priority=mp[mytask.name];
q.push(mytask);
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)
{
string str;
cin>>str;
myfun(str);
}
int len=q.size();
for(int i=0;i<len;i++)
{
string temp;
temp=q.top().name;
q.pop();
if(i<len-1) cout<<temp<<" ";
else cout<<temp;
}
}
}