栈的特点:先进后出 只有一个栈顶入口,从这个口入,从这个口出。
例题:反转字符串
输入:反转字符串个数
输出:反转后的字符串、
例:
INPUT: 1
olleh !dlrow
OUTPUT:
hello world!
STL stack使用来完成
stack<T>s | 定义栈,t为数据类型,如int float |
s.push(item) | 把item放到栈顶 |
s.top() | 返回栈顶元素但不删除 |
s.pop() | 删除栈顶元素,但不会返回。在出栈时需要执行两步操作,先使用top()获得栈顶元素,再使用pop()删除元素 |
s.size() | 返回栈顶元素 |
s.empty | 检查站是否为空,如果为空则返回true,否则返回false |
#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
scanf("%d",&n); //反转字符串的个数
getchar(); //吃掉输入个数后的回车防止对后面程序产生影响
while(n--) {
stack<char>s;
while(true) {
char ch=getchar(); //while(true)+getchar相当于可以输入字符串
if(ch==' '||ch=='\n'||ch==EOF) { //一次读入一个字符
while(!s.empty()) { //输出并清除栈顶
printf("%c",s.top());
s.pop();
}
if(ch=='\n'||ch==EOF) break;
printf(" ");
}
else s.push(ch);} //入栈
printf("\n");}
return 0;}
手写栈
#include<bits/stdc++.h>
using namespace std;
const int N=100100;
struct mystack{
char a[N]; //存放栈元素,字符型
int t=0; //栈顶位置
void push(char x){a[++t]=x;} //送入栈
char top(){return a[t];} //返回栈顶元素
void pop(){t--;} //弹出栈顶
int empty(){return t==0?1:0;} //返回1表示空
}st;
int main() {
int n; scanf("%d",&n);getchar();
while(n--){
while(true){
char ch=getchar();
if(ch==' '||ch=='\n'||ch==EOF) { //一次读入一个字符
while(!st.empty()) { //输出并清除栈顶
printf("%c",st.top());
st.pop();
}
if(ch=='\n'||ch==EOF) break;
printf(" ");
}
else st.push(ch);} //入栈
printf("\n");}
return 0;}
单调栈处理比较问题:
单调栈实际上是普通的栈,只是使用时保持栈内元素是单调的。例如,单调递减栈从栈顶到栈底是从小到大的顺序。当一个数入栈时,与栈顶比较,若比栈顶小,则入栈。若比栈顶,则弹出栈顶,直到这个属于能入栈为止。注意每个数都一定入栈
题解:从后向前遍历奶牛,并用一个栈保存从低到高的奶牛,栈顶的奶牛最矮;栈底的最高。具体操作:遍历到奶牛i时,将栈顶的奶牛与其进行比较,如果不比奶牛i高,就弹出栈顶,直到栈顶的奶牛比奶牛高,这就是奶牛的仰望对象,然后把i放进栈顶,栈中的奶牛仍然保持从低到高。
STL stack代码:
#include<bits/stdc++.h>
using namespace std;
const int N=100100;
int h[N],ans[N];
int main() {
int n; scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&h[i]);
stack<int>st;
for(int i=n;i>=1;i--){
while(!st.empty()&&h[st.top()]<=h[i])
st.pop();
if(st.empty()) ans[i]=0;
else ans[i]=st.top();
st.push(i);
}
for(int i=1;i<=n;i++)printf("%d\n" ,ans[i]);
return 0;}
手写栈代码:
#include<bits/stdc++.h>
using namespace std;
const int N=100100;
struct mystack{
char a[N]; //存放栈元素,字符型
int t=0; //栈顶位置
void push(char x){a[++t]=x;} //送入栈
char top(){return a[t];} //返回栈顶元素
void pop(){t--;} //弹出栈顶
int empty(){return t==0?1:0;} //返回1表示空
}st;
int h[N],ans[N];
int main() {
int n; scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&h[i]);
for(int i=n;i>=1;i--){
while(!st.empty()&&h[st.top()]<=h[i])
st.pop();
if(st.empty()) ans[i]=0;
else ans[i]=st.top();
st.push(i);
}
for(int i=1;i<=n;i++)printf("%d\n" ,ans[i]);
return 0;}