知识准备:
- 栈(stack)只允许在栈的一端插入或删除元素,这一端被称为栈顶;另一端称为栈底。
- 在C++的标准库中,
stack
在头文件<stack>
里面。 stack<T> s
定义了一个存储T类型数据的栈s。
例一:手动实现一个栈
#include<iostream>
using namespace std;
struct Stack{
int data[10000];
int top=-1;
void push(int x){
top++;
if(top<10000){
data[top]=x;
}else{
top--;
cout<<"stack overflow"<<endl;
}
}
void pop(){
if(top>=0){
top--;
}
}
int topval(){
if(top>=0){
return data[top];
}
}
};
int main(){
Stack s;
for(int i=1;i<=10;++i){
s.push(i);
}
for(int i=1;i<=10;++i){
cout<<s.topval()<<" ";
s.pop();
}
return 0;
}
例二:火车出入站
问题描述:
在火车调度站里,我们可以借助类似下图中的轨道,将火车车厢的顺序进行调整。我们都知道,火车的车厢是一节一节的,每一节都可以与前后分离,称为单独的一节。
这样的设计加上上面的轨道,通过合理的控制,我们就可以调节车厢之间的顺序了。但是并不是所有的出站顺序都是合法的。现在对于一种我们期望的出站顺序,作为火车站长,你需要知道这个顺序是否是合法的。
输入:
第一行输入火车车厢节数
第二行输入火车出站顺序
代码如下:
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
int main(){
int n;
cin>>n;
vector<int> a(n);
for(int i=0;i<n;++i){
cin>>a[i];
}
stack<int> s;
int cur=1;
bool f=1;
for(int i=0;i<n;++i){
while(s.empty()||s.top()!=a[i]&&cur<=n){
s.push(cur);
cur++;
}
if(s.empty()||s.top()!=a[i]){
f=0;
break;
}else{
s.pop();
}
}
if(f){
cout<<"legal"<<endl;
}else{
cout<<"illegal"<<endl;
}
return 0;
}
例三:括号匹配
代码如下:
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
char s[50005];
stack<int> st;
int ans[50005];
int main(){
scanf("%s",s);
int len=strlen(s);
bool f=true;
for(int i=0;i<len;++i){
if(s[i]=='('){
st.push(i+1);
}else{
if(!st.empty()){
ans[i+1]=st.top();
st.pop();
}else{
f=false;
break;
}
}
}
if(!st.empty()){
f=false;
}
if(!f){
printf("no\n");
}else{
printf("yes\n");
for(int i=1;i<=len;++i){
if(ans[i]){
printf("%d %d\n",ans[i],i);
}
}
}
return 0;
}
运行结果:
例四:汉诺塔1
例五 :汉诺塔2
问题描述:
现在小明开始玩汉诺塔问题,他放了2片黄金圆盘在第一根柱子上,从上到下依次编号为1~n,1号圆盘最小,n号最大。小明移动第i号圆盘需要花费i点力气,现在啊小明想把圆盘全部移动到第二根柱子上,那么小明完成游戏的最小移动次数和最少消耗的体力是多少?
输入:
输入一个正整数n(1<=n<=60)表示黄金圆盘的个数
输出:
一行输出2个数,第一个表示最小移动次数,第二个表示最小小号的体力,中间用一个空格隔开。
代码如下:
#include<cstdio>
long long f[60+5],g[60+5];
using namespace std;
int main(){
int n;
scanf("%d",&n);
f[1]=g[1]=1;
for(int i=2;i<=n;++i){
f[i]=2*f[i-1]+1;
g[i]=2*g[i-1]+i;
}
printf("%lld %lld\n",f[n],g[n]);
return 0;
}