zoukankan      html  css  js  c++  java
  • 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
    ",maxnum[x]);
                    break;
                }
            }
        }
        
        //fclose(stdin);
        //fclose(stdout);
        
        return 0;
    }
  • 相关阅读:
    河南省第十届ACM省赛G:Plumbing the depth of lake
    南洋理工oj 题目92 图像有用区域
    初学欧拉图,知识总结,后续增加
    初学并查集知识总结后续增加
    南阳oj 题目42 一笔画问题
    南阳oj 题目 90 整数划分
    南阳oj题目20吝啬的国度 菜鸟的进阶之路
    南阳oj 题目21 三个水杯
    UVA-540 Team Queue
    HDU-1596 find the safest road
  • 原文地址:https://www.cnblogs.com/Cindy-Chan/p/11191515.html
Copyright © 2011-2022 走看看