P5788 【模板】单调栈 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
学习单调栈!
不管是单调栈还是队列,思路大致相同,就是将即将进来的数与最后进的数进行比较来维护一最大或最小值,不过用处不同,单调栈一般用来找一个数的左边或者右边的第一个比它大或者比它小的数。
该题需要找到右边第一个比它大的数的序号。所以我们可以用栈来存放每个数的序号,这样既有序号又可以访问数值,不用再消耗空间。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[3000005];
int st[3000005],result[3000005];
int main()
{
int i,top=-1,n;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
{
while(top>-1&&a[i]>a[st[top]])//维护单调性遇到更大的数将前面的数逐一弹出
{
result[st[top]]=i;//在弹出数时用一个数组来收集结果
top--;
}
st[++top]=i;//当小于或者等于时都需要继续入栈
}
for(i=1;i<=n;i++)printf("%d ",result[i]);
}
P1981 [NOIP2013 普及组] 表达式求值 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
用栈来保存输入的值如果遇到’*‘先进行计算,最后将每个值进行累加。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll st[100000],a;
int main()
{
int top=-1;
char f;
cin>>a;
a%=10000;
st[++top]=a;//先将第一个取余后放入
while(cin>>f>>a)
{
if(f=='*')//遇到乘号就与栈顶的数进行计算
{
st[top]=st[top]*a%10000;
}
else{
st[++top]=a;//加号就直接放
}
}
a=0;
while(top>-1)
{
a+=st[top];//逐一进行累加计算
a%=10000;
top--;
}
printf("%lld\n",a);
}
P4387 【深基15.习9】验证栈序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
一开始时真的没有理解到题意,这不是需要全部入完栈再输出,在数没有入完则可以进行出栈操作,主要是样例也不提醒一下。
思路:当栈顶的数与出栈序列的头相等的是后就进行出栈操作,随着出栈序列的头后移,
当最后检查栈是否为空即可。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i,q,n,a[100005],b[100005];
cin>>q;
while(q--)
{
int n;
cin>>n;
stack<int>st;
for(i=1;i<=n;i++)//入栈序列
{
cin>>a[i];
}
for(i=1;i<=n;i++)//出栈序列
{
cin>>b[i];
}
int t=1;//头指针
for(i=1;i<=n;i++)
{
st.push(a[i]);
while(st.top()==b[t])//看栈顶的数是否和出栈序列的头相等,进行出栈和头后移
{
st.pop();
t++;
if(st.empty())
break;
}
}
if(st.empty())//看栈是否为空
cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}