题目
用户调度问题
在一个多任务系统中,有多个用户(User)和多个任务(Task),每个用户可以提交多个任务,每个任务都有一个唯一的优先级(Priority)。系统需要按优先级调度任务,即总是执行优先级最高的任务。如果多个任务的优先级相同,则选择提交这些任务中最早的用户。
现在给出用户提交的任务列表,请按照上述规则进行任务调度,并输出任务的执行顺序。
输入描述:
输入的第一行是两个整数 n 和 m,分别表示用户的数量和任务的数量。
接下来的 m 行,每行包含三个整数 user_id、task_id 和 priority,分别表示任务的提交用户ID、任务ID和任务的优先级。
输出描述:
输出任务的执行顺序,每行一个任务ID。
示例:
输入:
3 6
1 1 3
2 2 1
1 3 2
3 4 3
2 5 2
3 6 1
输出:
2
3
1
4
5
6
思路
- 数据结构选择:
- 使用一个优先队列(最小堆)来存储任务,其中每个元素包含任务ID、用户ID、优先级和提交时间(可以用任务在队列中的索引表示)。
- 使用一个哈希表来记录每个用户的首次提交时间(用于解决优先级相同的情况)。
- 任务插入:
- 遍历任务列表,将每个任务插入到优先队列中。
- 使用自定义的比较器,首先按优先级排序,如果优先级相同则按用户首次提交时间排序。
- 任务调度:
- 依次从优先队列中取出任务,输出任务ID。
Java 代码解析
import java.util.*;
class Task implements Comparable<Task> {
int taskId;
int userId;
int priority;
int submissionTime;
Task(int taskId, int userId, int priority, int submissionTime) {
this.taskId = taskId;
this.userId = userId;
this.priority = priority;
this.submissionTime = submissionTime;
}
@Override
public int compareTo(Task other) {
if (this.priority != other.priority) {
return Integer.compare(this.priority, other.priority); // Higher priority first
} else {
return Integer.compare(this.submissionTime, other.submissionTime); // Earlier submission time first
}
}
}
public class UserScheduling {
public static List<Integer> getTaskExecutionOrder(int n, int m, int[][] tasks) {
List<Task> taskList = new ArrayList<>();
Map<Integer, Integer> firstSubmissionTime = new HashMap<>();
int currentTime = 0;
for (int[] task : tasks) {
int userId = task[0];
int taskId = task[1];
int priority = task[2];
if (!firstSubmissionTime.containsKey(userId)) {
firstSubmissionTime.put(userId, currentTime);
}
taskList.add(new Task(taskId, userId, priority, firstSubmissionTime.get(userId)));
currentTime++;
}
PriorityQueue<Task> pq = new PriorityQueue<>(taskList);
List<Integer> executionOrder = new ArrayList<>();
while (!pq.isEmpty()) {
Task task = pq.poll();
executionOrder.add(task.taskId);
}
return executionOrder;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int[][] tasks = new int[m][3];
for (int i = 0; i < m; i++) {
tasks[i][0] = scanner.nextInt();
tasks[i][1] = scanner.nextInt();
tasks[i][2] = scanner.nextInt();
}
List<Integer> result = getTaskExecutionOrder(n, m, tasks);
for (int taskId : result) {
System.out.println(taskId);
}
}
}
C++ 代码解析
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
using namespace std;
struct Task {
int taskId;
int userId;
int priority;
int submissionTime;
bool operator>(const Task& other) const {
if (priority != other.priority) {
return priority > other.priority; // Higher priority first
} else {
return submissionTime > other.submissionTime; // Earlier submission time first
}
}
};
vector<int> getTaskExecutionOrder(int n, int m, const vector<vector<int>>& tasks) {
priority_queue<Task, vector<Task>, greater<Task>> pq;
unordered_map<int, int> firstSubmissionTime;
int currentTime = 0;
for (const auto& task : tasks) {
int userId = task[0];
int taskId = task[1];
int priority = task[2];
if (firstSubmissionTime.find(userId) == firstSubmissionTime.end()) {
firstSubmissionTime[userId] = currentTime;
}
pq.push({taskId, userId, priority, firstSubmissionTime[userId]});
currentTime++;
}
vector<int> executionOrder;
while (!pq.empty()) {
Task task = pq.top();
pq.pop();
executionOrder.push_back(task.taskId);
}
return executionOrder;
}
int main() {
int n, m;
cin >> n >> m;
vector<vector<int>> tasks(m, vector<int>(3));
for (int i = 0; i < m; i++) {
cin >> tasks[i][0] >> tasks[i][1] >> tasks[i][2];
}
vector<int> result = getTaskExecutionOrder(n, m, tasks);
for (int taskId : result) {
cout << taskId << endl;
}
return 0;
}
Python 代码解析
import heapq
from collections import defaultdict
class Task:
def __init__(self, taskId, userId, priority, submissionTime):
self.taskId = taskId
self.userId = userId
self.priority = priority
self.submissionTime = submissionTime
def __lt__(self, other):
if self.priority != other.priority:
return self.priority > other.priority # Higher priority first
else:
return self.submissionTime < other.submissionTime # Earlier submission time first
def get_task_execution_order(n, m, tasks):
pq = []
first_submission_time = defaultdict(int)
current_time = 0
for user_id, task_id, priority in tasks:
if user_id not in first_submission_time:
first_submission_time[user_id] = current_time
heapq.heappush(pq, Task(task_id, user_id, priority, first_submission_time[user_id]))
current_time += 1
execution_order = []
while pq:
task = heapq.heappop(pq)
execution_order.append(task.taskId)
return execution_order
if __name__ == "__main__":
n, m = map(int, input().split())
tasks = [list(map(int, input().split())) for _ in range(m)]
result = get_task_execution_order(n, m, tasks)
for task_id in result:
print(task_id)