zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    运算符和表达式详解
    超实用的Java web面试题
    80道最新java基础部分面试题(七)
    80道最新java基础部分面试题(六)
    80道最新java基础部分面试题(五)
    12道算法与编程面试题
    javaee和javase的区别
    2019年最新50道java基础部分面试题(四)
    2019年最新50道java基础部分面试题(三)
    2019年最新50道java基础部分面试题(二)
  • 原文地址:https://www.cnblogs.com/swm8023/p/2684666.html
Copyright © 2011-2022 走看看