模拟题。
有一个书架,你可以在书架上放书,下面有三种操作类型:
(1) L id 在书架的左边插入一本下标为id的书
(2) R id 在书架的右边插入一本下标为id的书
(3) ? id 从最左边或者最右边连续拿走几本书,使得下标为id的书变成书架上最左边的书或者最右边的数,求最少需要拿走几本书。
一开始我直接按照纯模拟去做的,用双向队列,可以前插和后插,但是超时了,因为每做一次查询几乎就是线性的时间。
后来发现可以用一个数组记录每个id的位置,再维护一下最左边和最右边的位置就行了,这样单点查询可以做到O(1).
还有一些细节就不再赘述了,比如每个id都是唯一的,最一开始的书怎么处理等等。
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <algorithm>
#include <deque>
#include <iostream>
#include <string>
using namespace std;
int q;
char c;
int id;
int temp[2 * 100000 + 5];
int main() {
scanf("%d", &q);
getchar();
int l = 100000;
int r = 100001;
while (q--) {
scanf("%c %d", &c, &id);
getchar();
if (c == 'L') {
temp[id] = l--;
}
else if (c == 'R') {
temp[id] = r++;
}
else {
printf("%d\n", min(temp[id] - l - 1, r - temp[id] - 1));
}
}
//system("pause");
return 0;
}