【2024华为OD-E卷-100分-用户调度问题】(题目+思路+Java&C++&Python解析)

题目

用户调度问题

在一个多任务系统中,有多个用户(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

思路

  1. 数据结构选择
    • 使用一个优先队列(最小堆)来存储任务,其中每个元素包含任务ID、用户ID、优先级和提交时间(可以用任务在队列中的索引表示)。
    • 使用一个哈希表来记录每个用户的首次提交时间(用于解决优先级相同的情况)。
  2. 任务插入
    • 遍历任务列表,将每个任务插入到优先队列中。
    • 使用自定义的比较器,首先按优先级排序,如果优先级相同则按用户首次提交时间排序。
  3. 任务调度
    • 依次从优先队列中取出任务,输出任务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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

执着的小火车

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值