【东华大学oj】单线程 CPU

单线程 CPU

作者: Turbo

时间限制: 1s

章节: 课程设计

问题描述

给你一个二维数组 tasks ,用于表示 n 项从 0 到 n - 1 编号的任务。其中 tasks[i] = [enqueueTimei, processingTimei] 意味着第 i 项任务将会于 enqueueTimei 时进入任务队列,需要 processingTimei 的时长完成执行。

现有一个单线程 CPU ,同一时间只能执行 最多一项 任务,该 CPU 将会按照下述方式运行:

    如果 CPU 空闲,且任务队列中没有需要执行的任务,则 CPU 保持空闲状态。

    如果 CPU 空闲,但任务队列中有需要执行的任务,则 CPU 将会选择 执行时间最短 的任务开始执行。如果多个任务具有同样的最短执行时间,则选择下标最小的任务开始执行。

    一旦某项任务开始执行,CPU 在 执行完整个任务 前都不会停止。

    CPU 可以在完成一项任务后,立即开始执行一项新任务。

返回 CPU 处理任务的顺序。

示例 1:

输入:

4

1 2

2 4

3 2

4 1

输出:

0 2 3 1

解释:事件按下述流程运行: 

- time = 1 ,任务 0 进入任务队列,可执行任务项 = {0}

- 同样在 time = 1 ,空闲状态的 CPU 开始执行任务 0 ,可执行任务项 = {}

- time = 2 ,任务 1 进入任务队列,可执行任务项 = {1}

- time = 3 ,任务 2 进入任务队列,可执行任务项 = {1, 2}

- 同样在 time = 3 ,CPU 完成任务 0 并开始执行队列中用时最短的任务 2 ,可执行任务项 = {1}

- time = 4 ,任务 3 进入任务队列,可执行任务项 = {1, 3}

- time = 5 ,CPU 完成任务 2 并开始执行队列中用时最短的任务 3 ,可执行任务项 = {1}

- time = 6 ,CPU 完成任务 3 并开始执行任务 1 ,可执行任务项 = {}

- time = 10 ,CPU 完成任务 1 并进入空闲状态

示例 2:

输入:

5

7 10

7 12

7 5

7 4

7 2

输出:

4 3 2 0 1

解释:事件按下述流程运行: 

- time = 7 ,所有任务同时进入任务队列,可执行任务项  = {0,1,2,3,4}

- 同样在 time = 7 ,空闲状态的 CPU 开始执行任务 4 ,可执行任务项 = {0,1,2,3}

- time = 9 ,CPU 完成任务 4 并开始执行任务 3 ,可执行任务项 = {0,1,2}

- time = 13 ,CPU 完成任务 3 并开始执行任务 2 ,可执行任务项 = {0,1}

- time = 18 ,CPU 完成任务 2 并开始执行任务 0 ,可执行任务项 = {1}

- time = 28 ,CPU 完成任务 0 并开始执行任务 1 ,可执行任务项 = {}

- time = 40 ,CPU 完成任务 1 并进入空闲状态

输入说明

输入若干行:

第一行为一个整数n代表二维数组tasks的行数。

后面n行,每行输入两个整数代表enqueueTimei和processingTimei

提示:

    tasks.length == n

    1 <= n <= 10^5

    1 <= enqueueTimei, processingTimei <= 10^9

输出说明

输出一行整数表示结果,每个整数的后面跟一个空格。

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;


struct Task {
    int enqueueTime;
    int processingTime;
    int index;
};

//对比任务时间
bool compareTasks(const Task& a, const Task& b) {
    return a.enqueueTime < b.enqueueTime;
}

struct Compare {
    bool operator()(const Task& a, const Task& b) {
        if (a.processingTime == b.processingTime) {
            return a.index > b.index;
        }
        return a.processingTime > b.processingTime;
    }
};

vector<int> cpuTaskOrder(vector<Task>& tasks) {
    int n = tasks.size();
    //排序
    sort(tasks.begin(), tasks.end(), compareTasks);

    // 最小堆
    priority_queue<Task, vector<Task>, Compare> minHeap;

    vector<int> result;
    int currentTime = 0;
    int index = 0;

    while (index < n || !minHeap.empty()) {
        // 如果没有任务在等待,将当前时间调整为下一个任务的 enqueueTime 
        if (minHeap.empty()) {
            currentTime = max(currentTime, tasks[index].enqueueTime);
        }

        //将所有在当前时间之前的任务加入到最小堆中
        while (index < n && tasks[index].enqueueTime <= currentTime) {
            minHeap.push(tasks[index]);
            index++;
        }

        //消除当前任务
        Task currentTask = minHeap.top();
        minHeap.pop();
        result.push_back(currentTask.index);
        currentTime += currentTask.processingTime;
    }

    return result;
}

int main() {
    int n;
    cin >> n;
    vector<Task> tasks(n);

    for (int i = 0; i < n; ++i) {
        cin >> tasks[i].enqueueTime >> tasks[i].processingTime;
        tasks[i].index = i;
    }

    vector<int> order = cpuTaskOrder(tasks);
    for (int i = 0; i < order.size(); ++i) {
        cout << order[i] << " ";
    }
    cout << endl;

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Juneeeeeeeeeeeee

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

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

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

打赏作者

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

抵扣说明:

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

余额充值