HDOJ 4699 Editor 对顶栈

编辑器 Editor

Time Limit: 1Sec   Memory Limit: 128 MB

Sample Input

8
I 2
I -1
I 1
Q 3
L
D
R
Q 2

Sample Output

2

3

Hint

The following diagram shows the status of sequence after each instruction:

分析:

最开始考虑到多次的插入、删除,我使用的链表。

但是由于涉及到求最大前缀和,每次都扫一遍会超时,于是学到了一种新方法:对顶栈,即指,光标两边分别是两个栈,靠近光标的两个字符分别为两个栈的栈顶,相当于提前计算了前缀和的最大值。

使用链表的版本:(会超时)

#include<cstdio>
#include<iostream>
#include<list>
using namespace std;

int main()
{
    list<int> l;
    std::list<int>::iterator it,q;
    it = l.begin();
    int n,x;
    char c;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        scanf("%c",&c);
        while(c<‘A‘ || c>‘Z‘)
        scanf("%c",&c);
        switch(c)
        {
            case ‘I‘://插入
            {
                scanf("%d",&x);
                l.insert(it,x);
                break;
            }

            case ‘D‘://删除
            {
                if(it != l.begin())
                {
                    q = it;
                    q--;
                    l.erase(q);
                }
                break;
            }

            case ‘L‘://向左移光标
            {
                if(it != l.begin())it--;
                break;
            }

            case ‘R‘://向右移光标
            {
                if(it != l.end())it++;
                break;
            }

            case ‘Q‘://求最长前缀和
            {
                scanf("%d",&x);
                int S = 0,maxx = 0,t = 0;
                for(q = l.begin();q != it;q++)
                {
                    t++;
                    if(t > x)break;
                    S += *q;
                    if(S > maxx)maxx = S;
                }
                cout<<maxx<<endl;
                break;
            }
        }
    }
    return 0;
}

使用对顶栈的版本:

#include<cstdio>
#include<iostream>
#include<list>
#include<stack>
#include<vector>
using namespace std;

int main()
{
    //freopen("editor.in","r",stdin);
    //freopen("editor.out","w",stdout);
    vector<int> num,maxnum;// num:前n项和  maxnum:前n项和中的最大值
    stack<int>a,b;//光标前后各为一个栈
    int n,x;
    char c;
    cin>>n;
    num.push_back(0);
    maxnum.push_back(-0xffffff);//maxnum记得初始化为负的极大值
    for(int i=1;i<=n;i++)
    {
        scanf("%c",&c);
        while(c<‘A‘ || c>‘Z‘)
        scanf("%c",&c);
        switch(c)
        {
            case ‘I‘:
            {
                scanf("%d",&x);
                a.push(x);
                num.push_back(x + num[num.size()-1]);
                maxnum.push_back(max(num[num.size()-1],maxnum[maxnum.size()-1]));
                break;
            }
            case ‘D‘:
            {
                if(!a.empty())// 判断栈是否为空 注意光标在最左端时无法删除
                {
                    a.pop();
                    num.pop_back();
                    maxnum.pop_back();
                }
                break;
            }
            case ‘L‘:
            {
                if(!a.empty())
                {
                    b.push(a.top());
                    a.pop();
                    num.pop_back();
                    maxnum.pop_back();
                }
                break;
            }
            case ‘R‘:
            {
                if(!b.empty())
                {
                    x = b.top();
                    a.push(b.top());
                    b.pop();
                    num.push_back(x + num[num.size()-1]);
                    maxnum.push_back(max(num[num.size()-1],maxnum[maxnum.size()-1]));
                }
                break;
            }
            case ‘Q‘:
            {
                scanf("%d",&x);
                printf("%d\n",maxnum[x]);
                break;
            }
        }
    }

    //fclose(stdin);
    //fclose(stdout);

    return 0;
}

原文地址:https://www.cnblogs.com/Cindy-Chan/p/11191515.html

时间: 2024-10-10 21:36:28

HDOJ 4699 Editor 对顶栈的相关文章

HDU 4699 - Editor - [对顶栈]

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4699 Problem Description Sample Input8I 2I -1I 1Q 3LDRQ 2 Sample Output23 Hint 题意: 维护一个整数序列的编辑器,有以下五种操作,操作总数不超过 $10^6$. $I \: x$:在当前光标位置之后插入一个整数 $x$,插入后光标移动到 $x$ 之后: $D$:删除光标前的一个整数: $L$:光标左移一格: $R$:光标右移一

HDOJ 4699 Editor 栈 模拟

用两个栈模拟: Editor Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1913    Accepted Submission(s): 591 Problem Description Sample Input 8 I 2 I -1 I 1 Q 3 L D R Q 2 Sample Output 2 3 Hint The fol

hdu 4699 Editor(双向链表+随便维护前缀和)

Editor Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1532    Accepted Submission(s): 480 Problem Description Sample Input 8 I 2 I -1 I 1 Q 3 L D R Q 2 Sample Output 2 3 Hint The following d

hdoj 3351 Seinfeld 【栈的简单应用】

Seinfeld Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1373    Accepted Submission(s): 678 Problem Description I'm out of stories. For years I've been writing stories, some rather silly, just

Hdu 4699 Editor(Splay)

题目大意: 给出一个文本编辑器,按照图示的操作进行删减和添加. 思路分析: 对于如何维护左边最大,就要记录每个区间的左边最大,还有这个节点的值,还有子区间的和. 注意看题目,题目的要求输出左边最大是不能为空集的,意味着如果全部都是负数,那么就输出最左边的负数就好. 那么就要解决初始化的问题. 再有一点问题就是会有很多个连续的L ,R操作.所以要判断边界. #include <cstdio> #include <iostream> #include <vector> #i

HDOJ4699(对顶栈)

#include<cstdio> #include<stack> #include<cstring> #include<algorithm> using namespace std; const int maxn=1000000; int Q1[maxn]; int Q2[maxn],r1,r2; int sum[maxn],dp[maxn]; int main(){ int n; while(scanf("%d",&n)!=EO

栈专题练习

HDU4699 Editor 使用"对顶栈",维护一下前缀和和最大前缀和就行了. 时间复杂度\(O(Q)\) #include<bits/stdc++.h> #define rg register #define il inline #define co const template<class T>il T read(){ rg T data=0,w=1; rg char ch=getchar(); while(!isdigit(ch)){ if(ch=='-

浅谈栈

所谓栈,就是一种先进后出的数据结构. 何为先进后出?想象一个箱子,你往箱底塞了一本语文书,然后往语文书上放数学书.假设箱子底面积与书的面积相同,那么你想把先放进去的语文书拿出来,就必须得先把放在上面的数学书拿出来.所以"先进"的语文书与数学书比较是"后出"的. 在代码中一个栈由一个数组\(stk\)和一个变量\(top\)组成,数组存信息,\([1,top]\)的空间都被占用了,下一次放元素就只能放在\(top+1\)这个位置然后让\(top=top+1\).拿元素

信息学竞赛知识点一览

C++语言 基础算法 位运算 快速幂 模拟 枚举 递推 递归 分治 二分 三分 排序 归并排序 离散化 倍增 贪心 高精度 数据结构 前缀和 差分 栈 对顶栈 单调栈 队列 双端队列 循环队列 单调队列 ST表 链表 链式前向星 Hash表 二叉堆 Huffman树 并查集 路径压缩 按秩合并 扩展域 边带权 树状数组 线段树 延迟标记 扫描线 动态开点线段树 分块 莫队 点分治 BST 平衡树 Treap Splay 红黑树 AVL SBT 替罪羊树 LCT CDQ分治 三维偏序 整体二分 可