Step01.栈
什么是栈?
栈是一种运算受限的线性表——仅在表尾进行插入和删除。插入的这一端被称为栈顶,相对地,把另一端称为栈底。
向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
因为最先进去的元素最后出来,所以栈称为FILO(First In Last Out)
栈的操作
做为一名懒人,我肯定不会手打栈,STL真™香。
定义方法:
stack<数据类型>变量名;
e.g: stack<int>s;
函数 | 功能 |
---|---|
top() | 取栈顶元素 |
push(x) | 将x压入栈 |
pop() | 删除栈顶元素 |
empty() | 判断栈是否为空(空为真) |
size() | 返回栈中元素个数 |
栈的使用
例题理解1:
后缀表达式求值(点击查看)
那么,后缀表达式就={
1.如果碰到运算符,让最近输入的两个数做运算,并记住这个结果的值。
2.在第1条不成立的情况下,将读入的值记录下来。
}
为了记录最近两个数的值,我们的栈就派上用场啦。PS:(因为栈"FILO")
于是我们的代码思路就出来啦:
当碰到数字就入栈,碰到运算符就取栈顶与次栈顶的值做运算再入栈。
最后输出栈顶元素就OK啦。
Code:
#include<bits/stdc++.h>
using namespace std;
int main(){
stack<int>s;
char a[1005];
while(scanf("%s",a)!=EOF){
if(a[0]=='+'||a[0]=='-'||a[0]=='*'||a[0]=='/'){
int k=s.top();s.pop();
int l=s.top();s.pop();
if(a[0]=='+')s.push(l+k);
if(a[0]=='-')s.push(l-k);
if(a[0]=='*')s.push(l*k);
if(a[0]=='/')s.push(l/k);
}else s.push(atof(a));
}cout<<s.top();
return 0;
}
例题理解2:
车厢调度(点击查看)
我们先不考虑此题的第②问,只讲第①问。
这道题的题目描述就很直接的告诉你了这个进站装置就是个栈嘛。
那我们为了让编号为i的火车从A->B,就必须让编号为前i-1的火车从A->B。(因为必须经过C站才能到达B站,是个栈装置,这个你能理解吧。)
我们用一个计数器m来表示当前已经入栈到C的火车编号,每输入一个数x时,让m~x这之间的数全部进栈。
如果此时栈顶就是x,那么出栈。否则说明达不到要求,输出NO,结束程序。
最后输出YES即可。
Code:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m=0;
cin>>n;
stack<int>s;
while(n--){
int x;
cin>>x;
while(x>m){
s.push(++m);
}if(s.top()==x)s.pop();
else{
cout<<"NO";
exit(0);
}
}cout<<"YES";
return 0;
}
栈的讲解就结束啦。
Step02.队列
什么是队列?
队列是一种特殊的线性表——它只允许在表的前端进行删除操作,而在表的后端进行插入操作。和栈一样,队列也是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
在队列中插入一个元素称为入队,从队列中删除一个元素称为出队。
因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除。故队列又称为FIFO(First In First Out)
队列的操作
做为一名懒人,我肯定不会手打队列,STL真™香。
定义方法:
queue<数据类型>变量名;
e.g: queue<int>q;
函数 | 功能 |
---|---|
back() | 取队尾元素 |
front() | 取队首元素 |
push(x) | 将x入队 |
pop() | 将队首元素出队 |
empty() | 判断队列是否为空(空为真) |
size() | 返回栈中元素个数 |
队列的使用
例题理解:
Blah数集(点击查看)
这道题要求第n项值,我们首先可以定义一个tot表示当前是第几项。
因为你不知道第tot项的值是多少,所以定义两个队列a,b分别表示数集里2x+1和3x+1的值。存下来比较是不是很香!
会有3种情况,分类讨论{
1.a.front()>b.front(){此时第tot项的值为b.front(),并且b.pop();}
2.a.front()<b.front(){此时第tot项的值为a.front(),并且a.pop();}
3.a.front()==b.front(){此时第tot项的值为谁的队首元素都行,并且a.pop(),b.pop();}
}
最后输出就行了。
Code
#include<bits/stdc++.h>
using namespace std;
int main(){
int x,n,tot=1;
cin>>x>>n;
queue<int>a,b;
while(tot<n){
a.push(2*x+1);
b.push(3*x+1);
if(a.front()>b.front()){
x=b.front();b.pop();
}else if(a.front()<b.front()){
x=a.front();a.pop();
}else{
x=a.front();
a.pop();b.pop();
}tot++;
}cout<<x;
return 0;
}
队列的讲解就结束啦。
呼呼,终于淦完第②篇知识总结啦。