百度&必应权4, 日IP1w+ 查看详情
自助收录

2023年华为OD机考真题:单核CPU任务调度

算法刷题2年前 (2023)更新 江南白衣
942 0 0
2023年华为OD机考真题:单核CPU任务调度

题目:单核CPU任务调度
知识点队列优先级队列
时间限制:1s 空间限制:256MB 限定语言:不限
题目描述:
现在有一个CPU和一些任务需要处理,已提前获知每个任务的任务ID、优先级、所需执行时间和到达时间。
CPU同时只能运行一个任务,请编写一个任务调度程序,采用“可抢占优先权调度”调度算法进行任务调度,规则如下:
如果一个任务到来时,CPU是空闲的,则CPU可以运行该任务直到任务执行完毕。但是如果运行中有一个更高优先级的任务到来,则CPU必须暂停当前任务去运行这个优先级更高的任务;
如果一个任务到来时,CPU正在运行一个比它优先级更高的任务时,新到达的任务必须等待;
当CPU空闲时,如果还有任务在等待,CPU会从这些任务中选择一个优先级最高的任务执行,相同优先级的任务选择到达时间最早的任务。
输入描述:
输入有若干行,每一行有四个数字(均小于108),分别为任务ID,任务优先级,执行时间和到达时间。每个任务的任务ID不同,优先级数字越大优先级越高,并且相同优先级的任务不会同时到达。
输入的任务已按照到达时间从小到达排列,并且保证在任何时间,处于等待的任务不超过10000个。
输出描述:
按照任务执行结束的顺序,输出每个任务的任务ID和对应的结束时间。
示例1
输入:
1 3 5 1
2 1 5 10
3 2 7 12
4 3 2 20
5 4 9 21
6 4 2 22
输出:
1 6
3 19
5 30
6 32
4 33
2 35
解题思路:
关键点:使用优先级队列PriorityQueue来放置任务。
1、任务1进来,因为当前队列为空,所以直接加入队列,记录任务开始时间为1
队列中:任务1(1 3 5 1)
2、任务2进来,求出两任务的时间间隙10-1=9,取队列中最上层任务1,所需时间为5,说明时间间隙中可以完成任务,输出第一个任务1 6;更新任务开始时间为10,将任务2放入队列
队列中:任务2(2 1 5 10)
3、任务3进来,求出两任务的时间间隙12-10=2,取队列中最上层任务2,所需时间为5,说明时间间隙中不能完成任务,因为有2个时间的间隙,所有需要更新任务2的所需时间5-2=3;更新任务开始时间为12,将任务3放入队列
队列中:任务3(3 2 7 12)、任务2(2 1 3 10)(任务3的优先级高于任务2)
4、任务4进来,求出两任务的时间间隙20-12=8,取队列中最上层任务3,所需时间为7,说明时间间隙中能完成任务3,输出3 19;而20-19=1,时间剩余1,再取队列最上层任务2,而任务2需要3个时间,所有不能完成,更新所需时间3-1=2;更新任务开始时间为20,将任务2和任务4放入队列
队列中:任务4(4 3 2 20)、任务2(2 1 2 10)(任务4的优先级高于任务2)
5、任务5进来,求出两任务的时间间隙21-20=1,取队列中最上层任务4,所需时间为2,所有不能完成,更新所需时间2-1=1;更新任务开始时间为21;将任务5和任务4放入队列
队列中:任务5(5 4 9 21)、任务4(4 3 1 20)、任务2(2 1 2 10)
6、任务6进来,求出两任务的时间间隙22-21=1,取队列中最上层任务5,所需时间为9,所有不能完成,更新所需时间9-1=8;更新任务开始时间为22;将任务6和任务5放入队列
队列中:任务5(5 4 8 21)、任务6(6 4 2 22)、任务4(4 3 1 20)、任务2(2 1 2 10)
7、遍历队列中的任务:
1)任务5:22+8=30、输出5 30
2)任务6:30+2=32、输出6 32
3)任务4:32+1=33、输出4 33
4)任务2:33+2=35、输出2 35
这个算法只有100分,错误的用例也是非常长,显示不全,有可能是需要使用BigDecimal,大家看看有什么其他问题!

全网最全面的华为OD机试真题汇总,100%原题题库,不需要开会员即可查看全部内容,更多考题请查看真题库。

真题库:https://www.yuque.com/codernav.com/od

代码实现:

package com.codernav.demo.hwod.exam;

import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Scanner;

/**
 * @title 单核CPU任务调度
 * @Description 现在有一个CPU和一些任务需要处理,已提前获知每个任务的任务ID、优先级、所需执行时间和到达时间。
 * CPU同时只能运行一个任务,请编写一个任务调度程序,采用“可抢占优先权调度”调度算法进行任务调度,规则如下:
 * 如果一个任务到来时,CPU是空闲的,则CPU可以运行该任务直到任务执行完毕。但是如果运行中有一个更高优先级的任务到来,则CPU必须暂停当前任务去运行这个优先级更高的任务;
 * 如果一个任务到来时,CPU正在运行一个比它优先级更高的任务时,新到达的任务必须等待;
 * 当CPU空闲时,如果还有任务在等待,CPU会从这些任务中选择一个优先级最高的任务执行,相同优先级的任务选择到达时间最早的任务。
 * @Author 开发者导航
 * @website https://codernav.com
 * @date 2023/5/28
 */
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        List<Task> tasks = new ArrayList<>();
        while (input.hasNextInt()) {
            //因为原题没有输出条件,所以这边使用for循环来完成输出
            //for(int i=0; i<8; i++){
            int id = input.nextInt();
            int p = input.nextInt();
            int need = input.nextInt();
            int start = input.nextInt();
            tasks.add(new Task(id, p, need, start));
        }
        //优先级队列
        PriorityQueue<Task> queue = new PriorityQueue<>();
        long time = 0;
        for (Task t : tasks) {
            //两任务开始的相隔时间
            long h = t.start - time;
            while (!queue.isEmpty() && h > 0) {
                if (h >= queue.peek().need) {
                    //中间的空余时间满足上一个任务执行
                    Task tmp = queue.poll();
                    //执行完上个任务所剩下的时间
                    h -= tmp.need;
                    //上个任务执行完的时间
                    time += tmp.need;
                    //输出执行完的任务
                    System.out.println(tmp.id + " " + time);
                } else {
                    Task tmp = queue.peek();
                    //更新任务的所需要时间(减去两任务之间的空余时间)
                    tmp.need -= h;
                    //更新时间
                    time += h;
                    //没有任务能完成直接退出
                    break;
                }
            }
            //更新时间
            if (time < t.start) time = t.start;
            //加入优先级队列
            queue.add(t);
        }
        //根据优先级输出任务
        while (!queue.isEmpty()) {
            Task t = queue.poll();
            time += t.need;
            System.out.println(t.id + " " + time);
        }
    }

    public static class Task implements Comparable<Task> {
        int id;
        int p;
        int need;
        int start;

        public Task(int id, int p, int need, int start) {
            this.id = id;
            this.p = p;
            this.need = need;
            this.start = start;
        }

        @Override
        public int compareTo(Task o) {
            if (this.p == o.p) {
                return this.start - o.start;
            }
            return o.p - this.p;
        }
    }
}
© 版权声明
开发者导航

相关文章

开发者导航

暂无评论

暂无评论...