【洛谷 B3656】【模板】双端队列 1 题解(链表)

143 阅读3分钟

【模板】双端队列 1

题目背景

Aya 衷心祝愿大家不再因为 std::deque() 重蹈覆辙。

题目描述

请你实现 mm 个双端队列,支持如下的 qq 次操作:

  • push_back(a,x):在第 aa 个双端队列中从尾部插入一个元素 xx
  • pop_back(a):在第 aa 个双端队列中从尾部弹出一个元素。
  • push_front(a,x):在第 aa 个双端队列中从头部插入一个元素 xx
  • pop_front(a):在第 aa 个双端队列中从头部弹出一个元素。
  • size(a):查询第 aa 个双端队列的元素个数;
  • front(a):查询第 aa 个双端队列的队首元素;
  • back(a):查询第 aa 个双端队列的队尾元素;

对于 pop_backpop_frontfrontback 操作,若当前双端队列为空则不进行,直接跳过该次操作。

输入格式

输入的第一行是一个正整数 qq,表示操作次数。

接下来 qq 行,每行先是一个字符串,保证为 push_back 或者 pop_back 或者 push_front 或者 pop_front 或者 size 或者 front 或者 back 之一。接下来是 1122 个正整数,分别表示 aaxx

输出格式

对于每个 size 或者 front 或者 back 操作,输出一行表示答案。

样例 #1

样例输入 #1

10
pop_back 2
push_back 1 1
push_front 1 3
push_front 2 2
push_front 2 3
pop_back 1
size 1
push_back 2 3
back 1
front 1

样例输出 #1

1
3
3

提示

【数据范围】

子任务mm \leqqq \leq分值
11101010101010
2220002000200020002020
3310510^510510^53030
4410610^610610^64040

对于所有数据,1m,q1061 \leq m,q \leq 10^61x1091 \leq x \leq 10^9


思路

首先定义一个包含双端队列的数组。每个双端队列由list类型表示。

然后从输入中读取操作数qq,并循环执行每个操作。每个操作首先读取一个字符串,该字符串表示要执行的操作类型。如果操作类型为"push",则还需要从输入中读取两个整数aaxx,其中aa表示要操作的队列的编号,xx表示要插入的元素。如果操作类型不是"push",则只需要读取整数aa

然后根据操作类型执行相应的操作。如果操作类型为"push_back",则在编号为aa的队列尾部插入元素xx。如果操作类型为"pop_back",则检查编号为aa的队列是否为空,如果不为空,则从队尾弹出一个元素。"push_front"和"pop_front"的操作与"push_back"和"pop_back"类似,只是操作的是队列的头部而不是尾部。

如果操作类型为"size",则输出编号为aa的队列的大小。如果操作类型为"front",则检查编号为aa的队列是否为空,如果不为空,则输出队首元素。"back"操作与"front"操作类似,只是输出的是队尾元素而不是队首元素。

注意

对于 pop_backpop_frontfrontback 操作,若当前双端队列为空则不进行,直接跳过该次操作。

if (dq[a].empty()) {
	continue;
}

AC代码

#include <iostream>
#include <list>
#define AUTHOR "HEX9CF"
using namespace std;

const int N = 1e6 + 7;

list<int> dq[N];

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	int q;
	cin >> q;
	for (int i = 1; i <= q; i++) {
		int a, x;
		string op;
		cin >> op;
		if (op.substr(0, 4) == "push") {
			cin >> a >> x;
		} else {
			cin >> a;
			x = 0;
		}
		// cout << op << " " << a << " " << x << "\n";
		if (op == "push_back") {
			dq[a].push_back(x);
		} else if (op == "pop_back") {
			if (dq[a].empty()) {
				continue;
			}
			dq[a].pop_back();
		} else if (op == "push_front") {
			dq[a].push_front(x);
		} else if (op == "pop_front") {
			if (dq[a].empty()) {
				continue;
			}
			dq[a].pop_front();
		} else if (op == "size") {
			cout << dq[a].size() << "\n";
		} else if (op == "front") {
			if (dq[a].empty()) {
				continue;
			}
			cout << dq[a].front() << "\n";
		} else if (op == "back") {
			if (dq[a].empty()) {
				continue;
			}
			cout << dq[a].back() << "\n";
		}
	}
	return 0;
}