队列
一、队列
1. 特点
队列是一种数据结构,它按照先进先出(First-In-First-Out,FIFO)的原则存储和访问数据。它类似于现实生活中排队的概念,最先进入队列的元素将最先被访问和删除,而最后进入队列的元素将最后被访问和删除。
2. 数组 / STL
2.1 存储
数组
int q[1010];
int head = 1, tail = 1;
STL
#include <queue>
queue <int> q;
2.2 操作
数组 | STL | |
---|---|---|
插入 | q[tail++] = x; |
q.push(x); |
删除 | head++; |
q.pop(); |
判空 | head == tail |
q.empty() |
队首 | q[head] |
q.front() |
队尾 | q[tail] |
q.back() |
大小 | tail-head |
q.size() |
3. 优先队列
3.1 存储
#include <queue>
priority_queue <int> q; // 越大优先级越高
priority_queue <int, vector<int>, greater<int> > q; // 越小优先级越高
3.2 操作
操作 | 程序 |
---|---|
插入 | q.push(x) |
删除 | q.pop() |
队首 | q.top() |
二、队列模板
1. 时间最近问题
这是很典型的一道时间最近问题,用一个队列可以保存离当前最近可能满足要求的事物。这个时候,当队头指向的元素超出时间范围,我们就认为其永远无法满足要求,然后踢出队列。
对于求出不同的国籍数量,我们可以用下面几种方法:
- 桶
程序:a[x]++; if (a[x] == 1) k++;
特点:支持动态运算
复杂度: O ( n ) O(n) O(n) - 排列
程序:if (a[i] != a[i-1] k++;
特点:略
时间复杂度: O ( n log n ) O(n \log n) O(nlogn) - 映射
程序:略
特点:略
时间复杂度: O ( n log n ) O(n \log n) O(nlogn)
参考程序如下:
#include <iostream>
using namespace std;
struct Node {
int x, t;
} q[300500];
int head = 1, tail = 1;
int n, ans;
int t, k, x;
int cnt[100100];
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> t >> k;
for (int j = 1; j <= k; j++) {
cin >> x;
cnt[x]++;
if (cnt[x] == 1) ans++;
q[tail++] = {
x, t};
}
while (head < tail) {
if (q[head].t + 86400 <= t) {
cnt[q[head].x]--;
if (cnt[q[head].x] == 0) ans--;
head++;
} else {
break;
}
}
cout << ans << endl;
}
return 0;
}
2. 队列模拟问题
这就是一道典型的队列模拟题。易错点主要有:
tail
指向待放入元素continue
不要写成break
- 每轮记得更新
flag = false
参考程序如下:
#include <iostream>
#include <cstdio>
using namespace std;
int cnt;
bool flag;
int m, n, x;
int q[1010];
int head = 1, tail = 1;
int main() {
cin >> m >> n;
for (int i