第四章 ALDS1_3_B:Queue 队列

知识点

队列

  • 规则:先入先出(First In First Out)
  • 操作
    • enqueue(x):在队列末尾添加元素x
    • dequeue():从队列开头取出元素
    • isEmpty():检查队列是否为空
    • isFull():检查队列是否已满
  • STL的queue类的成员函数,都是O(1)操作
    • size():返回队列的元素数
    • front():返回队头的元素
    • pop():从队列中取出队头并删除元素
    • push(x):在队列的末尾添加元素x
    • empty():在队列为空时返回true
  • 拓展
    • 为了充分利用数组的空间,可以将数组变成循环队列,也就是在到达数组最后位置后,从最开始的空间继续利用数组,前提是最开始的空间已经出队伍了,也就是队列未满。

问题链接

ALDS1_3_B:Queue

问题内容

CPU通过循环调度法逐一处理这些任务,对于每个任务最多只能处理q ms,若任务没有处理完,则将任务添加到队列最末尾,逐一输出已经完成的任务和任务的总耗时

思路

利用队列的思路去模拟调度的过程,并记录时间,当任务完成则输出即可。

代码

实现队列功能
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

const int maxx = 100000 + 10;
struct task {
    // 任务的名字和耗费的时间
    char name[100];
    int t;
};
task Queue[maxx];

// 指向队头和队尾的指针
int head, tail;


// 判断循环队列是否已满
bool isFull() {
    return head == (tail + 1) % maxx;
}

// 判断循环队列是否为空
bool isEmpty() {
    return head == tail;
}

// 将元素x添加到队列的末尾
void enqueue(task x) {
    Queue[tail] = x;
    // 循环队列
    tail = (tail + 1) % maxx;
}

// 返回队头元素并删除
task dequeue() {
    task x = Queue[head];
    // 循环队列
    head = (head + 1) % maxx;
    return x;
}
int main() {
    int n, q;
    scanf("%d %d", &n, &q);
    for (int i = 0; i < n; i++) {
        scanf("%s %d", Queue[i].name, &Queue[i].t);
    }
    // 当前已经有n个元素
    head = 0; tail = n;
    // 当前时间
    int nowtime = 0;
    while (!isEmpty()) {
        // 取出队头
        task u = dequeue();
        // 执行时间片 p 和 所需要时间u.t
        int c = min(q, u.t);
        // 任务执行了 c ms
        u.t -= c;
        // 当前时间加上c ms
        nowtime += c;
        // 任务还没做完,加入到队尾
        if (u.t > 0) {
            enqueue(u);
        }
        else { // 任务已经完成,打印出结果
            printf("%s %d\n", u.name, nowtime);
        }

    }
    return 0;
}
利用STL的queue类
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;

const int maxx = 100000 + 10;
struct task {
    // 任务的名字和耗费的时间
    char name[100];
    int t;
};
queue<task> Queue;

int main() {
    int n, q;
    scanf("%d %d", &n, &q);
    for (int i = 0; i < n; i++) {
        task t;
        scanf("%s %d", t.name, &t.t);
        Queue.push(t);
    }
    // 当前时间
    int nowtime = 0;
    while (!Queue.empty()) {
        // 取出队头
        task u = Queue.front();
        Queue.pop();
        // 执行时间片 p 和 所需要时间u.t
        int c = min(q, u.t);
        // 任务执行了 c ms
        u.t -= c;
        // 当前时间加上c ms
        nowtime += c;
        // 任务还没做完,加入到队尾
        if (u.t > 0) {
            Queue.push(u);
        }
        else { // 任务已经完成,打印出结果
            printf("%s %d\n", u.name, nowtime);
        }

    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值