lanqiaoOJ 3886:Windows的消息队列 ← 三元组+优先队列

【题目来源】
https://www.lanqiao.cn/problems/3886/learning/

【题目描述】
Windows 操作系统为每个进程维护一个消息队列,如果进程执行某种操作,例如单击鼠标等,系统向队列添加一个相应的消息。同时如果队列非空,则进程执行消息循环:根据消息的优先级取出一个消息,并执行相应的操作。注意,优先级数值小表示优先级高。在本题中,要求你模拟消息队列,向消息队列中添加消息和取出消息。

【输入格式】
输入数据占若干行,每行为一个命令:GET 或者 PUT,分别表示取出优先级最高的消息和添加消息。
如果是 PUT 命令,则命令后面紧跟一个字符串,代表消息名称(最多 10 个字符),然后是 2 个整数,分别代表消息的参数和优先级(优先级为小于 20 的正整数)。至多有 60000 个命令。
注意,每个消息可能会出现 2 次甚至更多次,测试数据保证任一时刻队列中各消息的优先级不一样(因此同一个消息虽然会出现多次,但任一时刻不会出现 2 条相同的消息,即任一时刻队列中的消息是不一样的)。

【输出格式】
对每个 GET 命令,输出从消息队列中取出的消息的名称和参数,如果消息队列为空,则输出 EMPTY QUEUE!;
对 PUT 命令,没有输出内容。

【输入样例】
GET
PUT msg1 10 5
PUT msg2 10 4
GET
GET
GET

【输出样例】
EMPTY QUEUE!
msg2 10
msg1 10
EMPTY QUEUE!

【说明】
多组输入,在 C++ 中可以使用 while(cin>>...);来处理。

【算法分析】
● 本题展示了利用三元组作为优先队列元素的处理方法。主要涉及函数 tie() 及 emplace()。
下面展示了将三元组作为优先队列元素并入队的核心代码。

cpp 复制代码
typedef tuple<int,string,int> T;
priority_queue<T,vector<T>,greater<T>> q;

        ...... ......

cin>>msg>>par>>pri;
q.emplace(pri,msg,par);

注意:
(1)虽然优先队列中的 push() 及 emplace() 函数都能实现将元素入队。但是,++针对三元组的入队,只能使用 emplace(),若用 push() 会报错++ 。
(2)利用 emplace() 入队三元组元素时,要注意三元组元素各个分量的顺序。因为,将三元组作为优先队列元素时,首先按第一个分量的大小进行自动排序的。若第一分量相同,再按第二个分量进行自动排序。其他分量以此类推。

● 代码 tie(pri,msg,par)=q.top(); 的解析
这行代码的作用是将三元组元素构成的队列的栈顶元素,解包后分别赋给三元组元素中的各变量pri、msg、par。

● 优先队列的 emplace() 方法:https://cplusplus.com/reference/queue/priority_queue/emplace/

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

priority_queue<string,vector<string>,less<string>> pq;

int main () {
    pq.emplace("orange");
    pq.emplace("strawberry");
    pq.emplace("apple");
    pq.emplace("pear");

    while(!pq.empty()) {
        cout<<pq.top()<<" ";
        pq.pop();
    }

    return 0;
}

/*
strawberry pear orange apple
*/

【算法代码一】

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

typedef tuple<int,string,int> T;
priority_queue<T,vector<T>,greater<T>> q;

int main() {
    string op,msg;
    int par,pri;
    while(cin>>op) {
        if(op=="PUT") {
            cin>>msg>>par>>pri;
            q.emplace(pri,msg,par);
        } else if(op=="GET") {
            if(!q.empty()) {
                tie(pri,msg,par)=q.top();
                cout<<msg<<" "<<par<<endl;
                q.pop();
            } else cout<<"EMPTY QUEUE!"<<endl;
        }
    }

    return 0;
}


/*
in:
GET
PUT msg1 10 5
PUT msg2 10 4
GET
GET
GET

out:
EMPTY QUEUE!
msg2 10
msg1 10
EMPTY QUEUE!
*/

【算法代码二】

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

typedef tuple<int,string,int> T;
priority_queue<T,vector<T>,greater<T>> q;

int main() {
    string op,msg;
    int par,pri;
    while(cin>>op) {
        if(op=="GET") {
            if(q.empty()) cout<<"EMPTY QUEUE!"<<endl;
            else {
                tie(pri,msg,par)=q.top();
                cout<<msg<<" "<<par<<endl;
                q.pop();
            }
        } else {
            cin>>msg>>par>>pri;
            q.emplace(pri,msg,par);
        }
    }
    
    return 0;
}


/*
in:
GET
PUT msg1 10 5
PUT msg2 10 4
GET
GET
GET

out:
EMPTY QUEUE!
msg2 10
msg1 10
EMPTY QUEUE!
*/

【参考文献】
https://www.lanqiao.cn/problems/3886/learning/

相关推荐
小龙报20 小时前
《算法通关指南算法千题篇(5)--- 1.最长递增,2.交换瓶子,3.翻硬币》
c语言·开发语言·数据结构·c++·算法·学习方法·visual studio
Cx330❀21 小时前
《C++ 多态》三大面向对象编程——多态:虚函数机制、重写规范与现代C++多态控制全概要
开发语言·数据结构·c++·算法·面试
_dindong21 小时前
【递归、回溯、搜索】专题六:记忆化搜索
数据结构·c++·笔记·学习·算法·深度优先·哈希算法
列逍21 小时前
list的模拟实现
数据结构·c++·list
小龙报1 天前
《算法通关指南:数据结构和算法篇 --- 顺序表相关算法题》--- 1.移动零,2.颜色分类
c语言·开发语言·数据结构·c++·算法·学习方法·visual studio
再睡一夏就好1 天前
【C++闯关笔记】使用红黑树简单模拟实现map与set
java·c语言·数据结构·c++·笔记·语法·1024程序员节
mifengxing1 天前
力扣每日一题——接雨水
c语言·数据结构·算法·leetcode·动态规划·
小龙报1 天前
《算法通关指南:数据结构和算法篇 --- 顺序表相关算法题》--- 询问学号,寄包柜,合并两个有序数组
c语言·开发语言·数据结构·c++·算法·学习方法·visual studio
晨非辰1 天前
《数据结构风云》递归算法:二叉树遍历的精髓实现
c语言·数据结构·c++·人工智能·算法·leetcode·面试