刚刚经历学校c++考试,作为一个上课摸鱼的小白,考得十分甚至九分的差,所以打算复习复习,正好了解到CSDN这一网站(上课搜代码不算:( ),打算写一写博客,顺便复习一下,望各位大佬捧捧场,有什么错误都可以指出!
这次出错,基础数据结构没学好是个重要原因,栈作为一个常用的,这次正好考到了,就决定着重复习一下。
基本特点:就是先入栈的数据后出栈,在某些时候用起来很方便。
针对栈的基本特点,有这样一道题:a b c d e依次进栈,问哪一个出栈顺序不合法:
A.a b c d e B.a b d c e C.a d c e b D.a d b c e
根据定义,很明显选D,画图模拟便知。
基本操作:
stack<type>s//定义
s.push(item)//入栈
s.top()//返回栈顶
s.pop()//删除栈顶
s.size()//返回大小
s.empty()//判断是否非空
while(!cow.empty()&&a[cow.top()]<=a[i]) cow.pop();
cow.push(i);
//单调栈,栈顶永远最小,栈底最大,从小到大排列
例题:洛谷P2947 [USACO09MAR]Look Up S
#include<bits/stdc++.h>
using namespace std;
int m,a[100001];
stack<int>cow;
int ans[100001];
int main()
{
cin>>m;
for(int i=1;i<=m;i++)
{
cin>>a[i];
}
for(int i=m;i>=1;i--)
{
while(!cow.empty()&&a[cow.top()]<=a[i]) cow.pop();
if(cow.empty()) ans[i]=0;
else ans[i]=cow.top();
cow.push(i);
}
for(int i=1;i<=m;i++)
{
cout<<ans[i]<<endl;
}
}
利用了栈的特点和单调栈,倒序找到最近的仰望对象,把复杂度降为O(n)。
P5788 【模板】单调栈
这里放一道题,有兴趣可以写写,只需小改上一题,cin改scanf(),cout改printf(),数组调大
代码如下:
#include<bits/stdc++.h>
using namespace std;
int m,a[4000001];
stack<int>cow;
int ans[4100001];
int main()
{
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d",&a[i]);
}
for(int i=m;i>=1;i--)
{
while(!cow.empty()&&a[cow.top()]<=a[i]) cow.pop();
if(cow.empty()) ans[i]=0;
else ans[i]=cow.top();
cow.push(i);
}
for(int i=1;i<=m;i++)
{
printf("%d ",ans[i]);
}
}
//哈哈,连cow都懒得改了
希望对大家复习有所帮助,记得捧场!