首先,普通的队列queue
就不再赘述
普通队列queue讲解
讲述一下双端队列deque
其实这两者的本质类似
deque
插入元素
在队尾插入为push_back
在队首插入为push_front
输出元素
输出队首元素为q.front()
输出队尾元素为q.back()
弹出元素
弹出队首元素为q.pop_front()
弹出队尾元素为q.pop_back()
deque<int> q; //创建 deque
q.push_back(1); // 从队尾插入 1
q.push_front(2); // 从队头插入 2
cout << q.front() << endl; // 输出队头元素
cout << q.back() << endl; // 输出队尾元素
while(q.size()) // 清空 deque
//q.pop_back();
q.pop_front();
题面
思路
各个数组的作用
q[num]
为
n
u
m
num
num的每个应用消息的位置
queue<pair<int, int> > tim
first为顺序,second为产生的应用
vis[i]
为第i个是否访问过
queue<int> q[maxn]; // 队列数组 保存每个应用的未读消息
queue<pair<int, int> > tim; // 保存全部消息 first存顺序 second存由哪个应用产生
int vis[maxn]; // 保存消息的读取状态
op=1时
把当前长度+1,分别在第num个应用中加入和tim中,当前位置+1
if(op == 1){
ans += 1;
q[num].push(cnt);
tim.push(make_pair(cnt, num));
cnt++;
}
op=2时
非常简单,把num应用的所有消息全部清除
else if(op == 2)
{
while(!q[num].empty()) // 请填写判断条件
{
vis[q[num].front()]=true;
q[num].pop();
ans--;
}
}
op=3时
在读取前num条消息时,由于tim中入队位置是从小往大走的,所以如果当前位置比num大,那么后面所有都比num大,并且要保证tim里面还有元素
如果读到一条未读消息,那么应该把当前给改为已读,并且把未读消息数-1,还要注意应该要把q[num]首位元素弹出,因为q[num]的入队肯定是从小到大入队,而且tim也是,所以当前这位肯定是q[num]里最小的这位也是首位元素
,所以将其弹出。
else
{
// 读取前num条消息
while(tim.size() && tim.front().first <= num)
{
// 如果读到的是一条未读消息
if(vis[tim.front().first]==false)
{
vis[tim.front().first]=true;
ans--;
q[tim.front().second].pop();
}
tim.pop();
}
}
整体实现
#include<bits/stdc++.h>
using namespace std;
const int maxn =3e5+10;
int op, num;
int n, T;
queue<int> q[maxn]; // 队列数组 保存每个应用的未读消息
queue<pair<int, int> > tim; // 保存全部消息 first存顺序 second存由哪个应用产生
int vis[maxn]; // 保存消息的读取状态
int main()
{
scanf("%d%d", &n, &T);
int cnt = 1; // 消息列表的长度+1
int ans = 0; // 未读消息的数量
while(T--)
{
scanf("%d%d", &op, &num);
if(op == 1)
{
ans += 1;
q[num].push(cnt);
tim.push(make_pair(cnt, num));
cnt++;
}
// 读取num应用产生的所有未读消息
else if(op == 2)
{
while(!q[num].empty()) // 请填写判断条件
{
vis[q[num].front()]=true;
q[num].pop();
ans--;
}
}
else
{
// 读取前num条消息
while(tim.size() && tim.front().first <= num)
{
// 如果读到的是一条未读消息
if(vis[tim.front().first]==false)
{
vis[tim.front().first]=true;
ans--;
q[tim.front().second].pop();
}
tim.pop();
}
}
printf("%d\n", ans);
}
return 0;
}