HDU 4286 Data Handler [栈,双端队列]

  这题比较容易想到的做法是splay,但是splay写起来比较麻烦而且每次操作都有LogN的复杂度,双向链表也是可以实现的,但实践起来比较麻烦,尤其是翻转操作。。。

  可以发现每次L或者R都是移动一位的,我们可以用更简单的数据结构来实现,用两个栈分别存L左边和R右边的数据,L和R中间的数据使用一个双端队列来保存,因为涉及到翻转操作,要用一个dir来表示当前的双端队列哪边是头哪边是尾。。。

  对于题目中给出的七种操作,都可以在O(1)的复杂度内实现,为了描述方便,左栈代表L左边数的栈,右栈代表R右边数的栈。

  1,MoveLeft L/R  左移左指针就是把左栈中栈顶的数弹到双端队列头部,左移右指针就是把队列尾部的元素放到右栈中。

  2,MoveRight L/R  右移左指针就是把队列头部元素放到左栈中,右移右指针就是把右栈顶元素弹到双端队列尾部。

  3,Insert L X   插入到队列头。

  4,Insert R X   插入到队列尾。

  5,Delete L    删除队列头元素。

  6,Delete R    删除队列尾元素。

  7,Reverse    dir^=1。

  

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define MAXN 1000005
 4 int cas,n,m,x[MAXN],l,r,tu;
 5 int stkl[MAXN],stkr[MAXN],topl,topr;
 6 int dq[MAXN*2],front,rear;
 7 struct list_q{
 8     int dir;
 9     void init(int l,int r,int n,int *x){
10         dir=0,topl=topr=0,front=MAXN,rear=MAXN-1;
11         for(int i=1;i<l;i++)stkl[++topl]=x[i];
12         for(int i=l;i<=r;i++)dq[++rear]=x[i];
13         for(int i=n;i>r;i--)stkr[++topr]=x[i];
14     }
15     void moveLR(char d,char p){
16         if(d=='L'&&p=='L')dq[dir?++rear:--front]=stkl[topl--];
17         else if(d=='L'&&p=='R')stkr[++topr]=dq[dir?front++:rear--];
18         else if(d=='R'&&p=='L')stkl[++topl]=dq[dir?rear--:front++];
19         else if(d=='R'&&p=='R')dq[dir?--front:++rear]=stkr[topr--];
20     }
21     void insert(char p,int v){
22         if(dir==0&&p=='R'||dir==1&&p=='L')dq[++rear]=v;
23         else dq[--front]=v;
24     }
25     void delet(char &p){
26         if(dir==0&&p=='R'||dir==1&&p=='L')rear--;
27         else front++;
28     }
29     void reverse(){dir^=1;}
30     void outans(int *x){
31         int p=0;
32         for(int i=1;i<=topl;i++)x[++p]=stkl[i];
33         for(int i=front;i<=rear;i++)x[++p]=dir?dq[rear-i+front]:dq[i];
34         for(int i=topr;i>0;i--)x[++p]=stkr[i];
35         for(int i=1;i<p;i++)printf("%d ",x[i]);printf("%d\n",x[p]);
36     }
37 };
38 char s1[15],s2[15];
39 int main(){
40     //freopen("test.in","r",stdin);
41     scanf("%d",&cas);
42     while(cas--){
43         list_q qq;
44         scanf("%d",&n);
45         for(int i=1;i<=n;i++)scanf("%d",&x[i]);
46         scanf("%d%d%d",&l,&r,&m);
47         qq.init(l,r,n,x);
48         for(int i=1;i<=m;i++){
49             scanf("%s",s1);
50             if(s1[0]!='R')scanf("%s",s2);
51             if(s1[0]=='I')scanf("%d",&tu);
52             switch(s1[0]){
53                 case 'M':qq.moveLR(s1[4],s2[0]);break;
54                 case 'I':qq.insert(s2[0],tu);break;
55                 case 'D':qq.delet(s2[0]);break;
56                 case 'R':qq.reverse();break;
57             }
58         }
59         qq.outans(x);
60     }
61 return 0;
62 }
原文地址:https://www.cnblogs.com/swm8023/p/2684666.html