这题比较容易想到的做法是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/archive/2012/09/14/2684666.html

HDU 4286 Data Handler [栈,双端队列]相关推荐

  1. C++数据结构和算法2 栈 双端/队列 冒泡选择插入归并快排 二三分查找 二叉树 二叉搜索树 贪婪 分治 动态规划

    C++数据结构和算法2 栈 双端/队列 冒泡选择插入归并快排 二三分查找 二叉树 二叉搜索树 贪婪 分治 动态规划 博文末尾支持二维码赞赏哦 _ github 章3 Stack栈 和 队列Queue= ...

  2. HDU - 7072 Boring data structure problem 双端队列 + 思维

    传送门 文章目录 题意: 思路: 题意: 你需要实现如下四个操作 q≤1e7q\le1e7q≤1e7 思路: 做的时候想了个链表的思路让队友写了,懒. 看了题解感觉题解还是很妙的. 你需要快速插入一个 ...

  3. 栈和队列之LinekedList(双端队列)

    介绍: ( deque,全名double-ended queue)是一种具有队列和栈的性质的数据结构.双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行. 双端队列是限定插入和删除操作 ...

  4. LeetCode 239. 滑动窗口最大值(双端队列+单调栈)

    文章目录 1. 题目信息 2. 解题 2.1 暴力法 2.2 双端队列法 1. 题目信息 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内 ...

  5. 单向队列、双端队列、栈的模型实现

    引言 自己实现简单的队列.栈的逻辑结构. 队列都包含头和尾两个指针,简单的单向队列只能在一端(如:head端)入列,在另一端(如:tail 端)出列:双端队列可以在 head 进出,也可以在 tail ...

  6. python数据结构与算法——栈、队列与双端队列

    栈 栈:是一种容器,可存入数据元素.访问元素.删除元素,它的特点在于只能允许在容器的一端进行加入数据和输出数据的运算.没有了位置概念,保证任何时候可以访问.删除的元素都是此前最后存入的那个元素,确定了 ...

  7. Boring data structure problem 模拟-双端队列

    题意 : 维护一个"双端队列",1e7次操作,支持左插入,右插入,按值删除,查找中点(靠右)值ceil[(m+1)/2]ceil[(m + 1) / 2]ceil[(m+1)/2] ...

  8. STL源码剖析 stack 栈 概述->(使用deque双端队列 / list链表)作为stack的底层容器

    Stack是一种先进后出的数据结构,他只有一个出口 stack允许 新增元素.移除元素.取得最顶端的元素,但是无法获得stack的内部数据,因此satck没有遍历行为 Stack定义的完整列表 (双端 ...

  9. 【数据结构】队列-顺序队列、循环队列、链队、双端队列

    定义 队列是只允许在一端进行插入,而在另一端进行删除的线性表. 队头(Front):允许删除的一端,又称为队首. 队尾(Rear): 允许插入的一端. 先进入队列的元素必然先离开队列,即先进先出(Fi ...

最新文章

  1. 如何在Ubuntu/CentOS上安装Linux内核4.0
  2. POJ 3126 Prime Path(筛法,双向搜索)
  3. 「微信小程序免费辅导教程」24,基础内容组件icon的使用探索与7月26日微信公众平台的更新解读...
  4. electron开发
  5. 博客园代码高亮显示教程
  6. win7-安装phantomjs,并添加环境变量。
  7. urllib.request.urlopen(req).read().decode解析http报文报“‘utf-8‘ codec can‘t decode”错处理
  8. [知识点]C++中STL容器之set
  9. pt-osc全解pt-online-schema-change
  10. Linux:写一个简单的服务器
  11. Smart3D三维建模操作笔记
  12. 超级搜索术6-问题驱动/系统思维
  13. 动态规划练习一之最低通行费
  14. Netty网络编程第七卷
  15. 请总结描述用户和组管理类命令的使用方法并完成以下练习
  16. html将页面分成四部分,将HTML页面拆分为定义的宽度和高度部分
  17. 批量修改照片名称的快速方法
  18. 微信小程序input禁止输入特殊表情符号与空格
  19. centos7安装WGCLOUD说明
  20. 实验一 机械臂正逆运动学

热门文章

  1. Linux Shell编程 test命令
  2. Kotlin 简化Fragment使用的扩展方法
  3. 深度 | 人工智能的游戏征途:超级玛丽简直小菜一碟,星际争霸、LOL才是大boss...
  4. 满洲里市智慧教育建设跨入云时代
  5. 2017年智能家居将从概念走进现实
  6. 移动端触屏click点击事件延迟问题,以及tap的解决方案
  7. ExtJS FormPanel不执行校验
  8. 英特尔支持员工自带设备办公
  9. JavaScript 中运算符的优先级
  10. MySQL 中的运算符