Editor

2 篇文章 0 订阅

题目大意

维护一个整数序列的编辑器,有以下五种操作,操作总数不超过10 6 6
1.I x:在当前光标位置之后插入一个整数x,插入后光标移动到x以后
2.D:删除光标之前的一个整数,即按下退格键Backspace
3.L:光标向左移动一个位置,即按下←键
4.R:光标向右移动一个位置,即按下→键
5.Q k:询问在位置k之前的最大前缀和,其中k不超过当前光标的位置

解题思路:

对顶栈
可以用cpp自带骚库stack
我们定义两个栈,第一个栈是光标前,后一个栈是光标后
于是问题就不难,插入时直接把元素加入第一个栈,删除直接把第一个栈的栈顶元素弹出去,左移就弹出第一个栈的栈顶元素插入到第二个栈中,右移则弹出第一个栈的栈顶元素插入到第一个栈中
至于前缀和,我们设sum[i]为在光标在i处时前面所有数的前缀和,dp[i]为位置i前的最大前缀和,now为第一个栈的元素数量
于是 sum[now]=sum[now-1]+x;
dp[now]=max(dp[now-1],sum[now]);
这样就硬生生的转换为一道简单的模拟题了

Accepted code:

#include<stack>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define maxn (int)(1e6+50)
using namespace std;
int sum[maxn],dp[maxn];
stack<int> fir;
stack<int> sec;
int main()
{
    int m,x;
    char c[15];
    while(~scanf("%d",&m))
    {
        while(fir.size()) fir.pop();
        while(sec.size()) sec.pop();
        int now=0;
        dp[0]=-1e9;
        sum[0]=0;//初始化
        while (m--)
        {
            scanf("%s",c);
            if (c[0]=='I')
            {
                scanf("%d",&x);
                fir.push(x);
                now++;
                sum[now]=sum[now-1]+x;
                dp[now]=max(dp[now-1],sum[now]);
            }
            else
            if (c[0]=='D')
            {
                if (!now) continue;
                now--;
                fir.pop();
            }
            else
            if (c[0]=='L')
            {
                if (!now) continue;
                now--;
                sec.push(fir.top());
                fir.pop();
            }
            else
            if (c[0]=='R')
            {
                if (!sec.size()) continue;
                now++;
                fir.push(sec.top());
                sec.pop();
                sum[now]=sum[now-1]+fir.top();
                dp[now]=max(dp[now-1],sum[now]);
            }
            else
            {
                scanf("%d",&x);
                printf("%d\n",dp[x]);
            }
        }
    }
    return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值