方案1+离线处理+一维数组+偏移量


AC代码如下:
cpp
#include <bits/stdc++.h>
using namespace std;
#define maxn 1000010
int dq[maxn*3];//具体的一个双端队列数据
struct node{
int head,tail,first;//first=0,队列还未建
}dq_info[maxn];//每个双端队列的信息
struct node2{
int a,x,sq,output;//output输出信息
char cmd[11];
}op_info[maxn];//操作信息
int cmp1(node2 a,node2 b){//操作信息按队列号排序,若相同,按操作序号排列
if(a.a!=b.a)return a.a<b.a;
return a.sq<b.sq;
}
int cmp2(node2 a,node2 b){//操作信息按操作序号排列
return a.sq<b.sq;
}
int main(){
int q,i,a,x,head,tail;
char cmd[11];
scanf("%d",&q);
for(i=1;i<=q;i++){//离线处理,先存储输入信息
scanf("%s",cmd);
strcpy(op_info[i].cmd,cmd);
if(cmd[0]=='p'&&cmd[1]=='u'){
scanf("%d%d",&a,&x);
op_info[i].x=x;
}else{
scanf("%d",&a);
}
op_info[i].sq=i;//记录操作序列
op_info[i].a=a;
}
sort(op_info+1,op_info+1+q,cmp1);
for(i=1;i<=q;i++){//离线处理
if(op_info[i].cmd[0]=='p'&&op_info[i].cmd[1]=='u'){
a=op_info[i].a;
if(dq_info[a].first==0||dq_info[a].head+1==dq_info[a].tail){//AC
dq_info[a].first=1;
dq_info[a].head=1e6+10;
dq_info[a].tail=1e6+10+1;
}
if(strcmp(op_info[i].cmd,"push_back")==0){//strcmp("a","a")反常,字符串雷同,值为0
dq[dq_info[a].tail++]=op_info[i].x;
}else{//"push_front"
dq[dq_info[a].head--]=op_info[i].x;
}
}else if(strcmp(op_info[i].cmd,"pop_back")==0){
a=op_info[i].a;
if(dq_info[a].first==0||dq_info[a].head+1==dq_info[a].tail);
else dq_info[a].tail--;
}else if(strcmp(op_info[i].cmd,"pop_front")==0){
a=op_info[i].a;
if(dq_info[a].first==0||dq_info[a].head+1==dq_info[a].tail);
else dq_info[a].head++;
}else if(strcmp(op_info[i].cmd,"back")==0){
a=op_info[i].a;
if(dq_info[a].first==0||dq_info[a].head+1==dq_info[a].tail);
else op_info[i].output=dq[dq_info[a].tail-1];
}else if(strcmp(op_info[i].cmd,"front")==0){
a=op_info[i].a;
if(dq_info[a].first==0||dq_info[a].head+1==dq_info[a].tail);
else op_info[i].output=dq[dq_info[a].head+1];
}else if(strcmp(op_info[i].cmd,"size")==0){
a=op_info[i].a;
if(dq_info[a].first==0||dq_info[a].head+1==dq_info[a].tail);
else op_info[i].output=dq_info[a].tail-dq_info[a].head-1;
}
}
sort(op_info+1,op_info+1+q,cmp2);//复原操作顺序
for(i=1;i<=q;i++){
if(strcmp(op_info[i].cmd,"size")==0||op_info[i].output!=0)
printf("%d\n",op_info[i].output);
}
return 0;
}
方案2+stl list


cpp
#include <bits/stdc++.h>
using namespace std;
#define maxn 1000010
char cmd[20];
//1个双端队列好实现,但是10^6个体量的双端队列,空间遇到了问题,每个队列用数组实现吗?
//开动态数组,空间应该不成问题。
//编的过程中,发现,头部没有留空间,咋办。
//瞟了一样双端队列图,感觉能靠两个数组实现,实现起来会有些变扭,不如队列那么顺手
//编的过程中,感受到了难度,数据会存在跨越两个数组,感觉有点难办。
//细节上,两个数组的初始位置0,不能很好的融合,难办。
//看了一些实现,竟然只要让数组从中间位置开始,如100005,向两头拓展。
list<int> q[maxn];
int main(){
int T,a,x;
scanf("%d",&T);
while(T--){
scanf("%s",cmd);
if(strcmp(cmd,"push_back")==0){//两字符串相同,返回值是0
scanf("%d%d",&a,&x);
q[a].push_back(x);
}else if(strcmp(cmd,"pop_back")==0){
scanf("%d",&a);
if(q[a].empty())continue;
else q[a].pop_back();
}else if(strcmp(cmd,"push_front")==0){
scanf("%d%d",&a,&x);
q[a].push_front(x);
}else if(strcmp(cmd,"pop_front")==0){
scanf("%d",&a);//漏了此句,查了1小时
if(q[a].empty())continue;
else q[a].pop_front();
}else if(strcmp(cmd,"size")==0){
scanf("%d",&a);
printf("%d\n",q[a].size());
}else if(strcmp(cmd,"front")==0){
scanf("%d",&a);
if(q[a].empty())continue;
else printf("%d\n",q[a].front());
}else if(strcmp(cmd,"back")==0){
scanf("%d",&a);
if(q[a].empty())continue;
else printf("%d\n",q[a].back());
}
}
return 0;
}