关键词:最小堆,拓扑排序,字符串
试题链接:
任务调度
问题描述:
思路:
前序任务比较多的任务的优先度应该设定为较低值,可以把一个任务的前序任务数。
这道题的大体思路是:
先声明一个数据结构node,记录任务名称,任务的前序任务数。在优先队列里将前序任务数的任务优先级设定为较低值。对于输入的每一行,首先将当前行任务存入map中(如果是第一次出现),再将括号其后序任务存入map中(如果是第一次出现),并修改其前序任务数。
备注:
priority_queue 容器适配器定义了一个元素有序排列的队列。默认队列头部的元素优先级最高。因为它是一个队列,所以只能访问第一个元素,这也意味着优先级最高的元素总是第一个被处理。
感想:
个人感觉处理字符串还是python要方便一点。目前我做题的注意力还是不够集中,答题思路对了但总是会遗漏一些微不足道的地方,放进本地跑好久才找到问题…python虽慢但是稍微简练一点可能能避免很多问题…
解决方案:
#include<iostream>
#include<queue>
#include<map>
#include<string>
using namespace std;
struct node {
string name;
int num;
friend bool operator < (node n1, node n2) {
//前序任务多的优先级低
if (n1.num != n2.num) {
return n1.num > n2.num;
}
else {
//前序任务相同,则按照字典序排列
return n1.name > n2.name;
}
}
};
int main() {
int n;
cin >> n;
priority_queue<node> pq; //优先队列
map<string, node> mp; //map方便访问
for (int i = 0; i < n; i++) {
string tmp;
cin >> tmp;
//遍历输入的字符串
int j = 0;
for (j = 0; j < tmp.size(); j++) {
if (tmp[j] == '(') {
break;
}
}
string t = tmp.substr(0, j); //获取任务
if (mp.count(t) == 0) //任务不在map中
{
node nd;
nd.name = t;
nd.num = 0;
mp[t] = nd;
}
for (int k = j; k < tmp.size(); k++) {
if (tmp[k] == ',' || tmp[k] == ')') {
//后序任务数量增加,vector存储
string latetask = tmp.substr(j + 1, k-j-1);
if (latetask != "NULL") {
//后序任务没存入列表
if (mp.count(latetask) == 0) {
node nd;
nd.name = latetask;
nd.num = 1;
mp[latetask] = nd;
}
else {
//后序任务的前序任务数+1
mp[latetask].num++;
}
j = k;
}
}
}
pq.push(mp[t]); //令当前任务入队
}
for (int i = 0; i < n; i++) {
cout << pq.top().name << " ";
pq.pop();
}
return 0;
}
下面是大佬的用python写的解决方案,真就,太凝练了,tql,学习了:
# -*- coding: utf-8 -*-
res = []
for _ in range(int(input())):
#-1去掉右括号,把NULL替换成u(比'Task'大就好),排序会靠后
task = input()[:-1].replace('NULL', 'u').split('(')
#将后序任务也进行排序,后序任务排在前序任务的后面
res.append([task[0], sorted(task[1].split(','))])
#以后序任务为首要,再以前序任务为次要排序
res.sort(key=lambda x: (x[1], x[0]))
print(" ".join(i[0] for i in res))
断点一点点调试了这个代码的每一步:
task = input()[:-1].replace(‘NULL’, ‘u’).split(’(’)
res.append([task[0], sorted(task[1].split(’,’))])
然后输入完毕后res:
一点点观察了一遍只觉得是我看了下次也写不出来的东西,之后加油吧。