AcWing 128编辑器

一道对顶栈 思路和修改过程


#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e6+9; int f[maxn],cnt; //最大前缀和 光标左边元素个数 stack<int>a;//光标左边 stack<int>b;//光标右边 int sum[maxn],maxsum; //前缀和 最大前缀和 //本来想只用两个变量记录 后来发现无法实现删除操作 int main() { int q; scanf("%d",&q); //每次操作维护的值:栈顶元素 光标位置 前缀和 当前位置的最大前缀和 memset(f,-63,sizeof f);//考虑负数的情况 将最大值的初值赋为极小值 for(int i=1;i<=q;i++) { char s; int x; cin>>s; if(s=='I') {//插入 scanf("%d",&x); a.push(x); cnt++;// sum[cnt]=sum[cnt-1]+x; //sum[++cnt] if(sum[cnt]>f[cnt-1]) {//如果当前前缀和大于上一个最大前缀和 f[cnt]=sum[cnt];//最大前缀和就等于当前的前缀和 } else { f[cnt]=f[cnt-1];//否则最大前缀和等于上一个最大前缀和 } //可优化:三目运算符 } if(s=='D') {//删除前一个元素 if(!a.empty()) {//栈为空可跳过 a.pop();//删除栈顶元素 cnt--;//下标-1 } } if(s=='L') {//左移光标 if(a.empty()) continue;//栈为空可跳过 b.push(a.top());//将光标左边的元素添加到右边 a.pop();//删除左边元素 cnt--;//下标-1 } if(s=='R') {//右移光标 if(b.empty()) continue; a.push(b.top());//将光标右边的元素添加到左边 b.pop();//删除右边元素 cnt++;//下标+1 sum[cnt]=sum[cnt-1]+a.top();//更新前缀和 //调了半天 问题出在这里 后面加的x 而这个操作没有更新x的值 //添加的是光标右边(已移动到左边)的值 所以应该+a.top()而不是x if(sum[cnt]>f[cnt-1]) { f[cnt]=sum[cnt]; } else { f[cnt]=f[cnt-1]; } } if(s=='Q') {//询问最大前缀和 scanf("%d",&x); printf("%d\n",f[x]); } //调试 // for(int j=1;j<=q;j++) // { // cout<<sum[j]<<' '; // } // cout<<endl; // for(int j=1;j<=q;j++) // { // cout<<f[j]<<' '; // } // cout<<endl; } return 0; } //一次修改 忽略栈为空可以跳过 导致段错误 //二次修改 R操作加错数 WA //三次修改 忽略负数的情况 最大值是负数的话输出0 WA

 

posted @ 2022-09-15 09:42  Mercury1004  阅读(33)  评论(0)    收藏  举报