Bootstrap

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

【模板】双端队列 1

题目背景

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

题目描述

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

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

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

输入格式

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

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

输出格式

对于每个 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

提示

【数据范围】

子任务 m ≤ m \leq m q ≤ q \leq q分值
1 1 1 10 10 10 10 10 10 10 10 10
2 2 2 2000 2000 2000 2000 2000 2000 20 20 20
3 3 3 1 0 5 10^5 105 1 0 5 10^5 105 30 30 30
4 4 4 1 0 6 10^6 106 1 0 6 10^6 106 40 40 40

对于所有数据, 1 ≤ m , q ≤ 1 0 6 1 \leq m,q \leq 10^6 1m,q106 1 ≤ x ≤ 1 0 9 1 \leq x \leq 10^9 1x109


思路

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

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

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

如果操作类型为"size",则输出编号为 a a a的队列的大小。如果操作类型为"front",则检查编号为 a a a的队列是否为空,如果不为空,则输出队首元素。"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;
}

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;