sicily 1443. Printer Queue

【题意解析】

有一个打印工作的队列,每个工作有一个优先级(范围0~9),数值越大,优先级越高。打印顺序要按照优先级由高到低,因此如果队列头的工作的优先级不是整个队列中最大的,那么就必须回到队列尾继续等待。如果队列头的工作优先级是最高的,那么就执行这个打印工作,并将其从队列中删除。

给定队列的长度和你的工作所在的位置(位置标号从队列头开始为0、1、2、3...n-1),要求出完成你的打印工作所需要的时间(包括打印你自己的那个时间)。注意,打印一个工作的时间为1,从队列头移到队列尾不计时间。

【思路提示】

方法1:直接使用queue来模拟这个过程。

我的实现:

使用priority_queue维护整个队列的优先级信息,每次可以直接取出最大的优先级。用一个数组存放初始的队列,数组值为每个位置的优先级。用数组下标index来记录队列头的位置,将队列头移到队列尾的操作转换为下标的移动。当下标所指的工作可以被打印,则将其优先级改为-1(比最小优先级小),时间加1,从优先队列中删除这个最大的优先级(也即删除priority_queue的队列头)。结束条件为当前工作的优先级最大,且下标index等于你的工作所在的位置m。

【代码】

#include<iostream>
#include<queue>
#include<string.h>
using namespace std;

int main(){
    int n, m, t, hightest, index, time;
    int priority[101];
    cin >> t;
    while (t--){
        cin >> n >> m;
        for (int i = 0; i < n; ++i)
            cin >> priority[i];
        int my_pri = priority[m];
        priority_queue<int> pq(priority, priority+n);
        index = 0;
        time = 0;
        hightest = pq.top();
        while (my_pri < hightest || index != m){
            if (hightest <= priority[index]){
                time++;
                priority[index] = 0-1;
                pq.pop();
                hightest = pq.top();
            }
            index++;
            if (index >= n)
                index = 0;
            
        }
        cout << time+1 << endl;
    }
    return 0;
}                                


【疑问】

起初,我采用的是用另外一个数组printed[101]来记录一个工作是否被打印,而不是采用修改已经打印的工作的优先级。为了能够再优化一点点,我在循环体末尾增加循环判断,如果下标所指的工作已经打印,就继续移动下标而不是进入下一次循环。试了好几个测例都没错,但是就是WA,不知是哪里出问题了。有知道的欢迎指教。

while (my_pri < hightest || index != m){
            if (hightest <= priority[index]){
                time++;
                printed[index] = 1;
                pq.pop();
                hightest = pq.top();
            }
            index++;
            while (printed[index] == 1)
                index++;
            if (index >= n)
                index = 0;
            
        }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值