1.概述
1.1 简介
栈是一种极为常用的数据结构,有两种基本操作:push和pop,这两种操作都限制在栈顶。push是从栈顶压入元素,即入栈;pop是弹出栈顶元素,即出栈。在出栈时,要判断栈是否为空。
可以用静态数组来模拟栈,但编译时需要指定数组的大小,即栈的大小是固定的。还可以用类似链表的struct实现,不需要指定大小。
栈在C++的<stack>容器中全封装好了:.pop( )是出栈操作, .push( )是入栈操作, .empty( )判断栈是否为空, .top( )返回栈顶元素。
1.2 入栈出栈
描述:n个元素以1 2 ... n顺序入栈,求出栈序列有多少种。
元素的出栈情况比较复杂:可以一入栈就出栈,也可以入栈后等若干个元素入栈后再依次出栈。比如,有三个元素1、2、3,并按1 2 3的顺序入栈,其出栈序列:(1)1 2 3入栈后开始出栈,则出栈序列为3 2 1。(2)1 2入栈后开始出栈,2出栈后3入栈,此时栈中元素是3 1,出栈序列为2 3 1;也有可能2 1出栈后3入栈,则出栈序列为2 1 3。(3)……
n个元素的出栈序列的种数为C(2n,n)/(n+1),该数叫做Catalan数,具体的证明参看这里。
2. 问题
2.1 九度OJ 1108
模拟栈,根据要求输出结果。
源代码:
1108 | Accepted | |
908KB | 1083B | 20MS | C / 代码 |
#include "st@R_404[email protected]" #include "stdlib.h" typedef struct stack { int data; struct stack*next; }stack; static stack*top; int is_empty() { return top==NULL; } void push(int a) { stack*p; p=(stack*)malloc(sizeof(stack)); p->data=a; p->next=top; top=p; } void pop() { stack*q; q=top; top=top->next; free(q); } int main() { int i,m,count; char ch[10]; while(~scanf("%d",&count)) { top=(stack*)malloc(sizeof(stack)); top=NULL; if(count>0) { for(i=count;i>=1;i--) { scanf("%s",&ch); if(ch[0]=='A') { if(is_empty()) printf("E\n"); else printf("%d\n",top->data); } else if(ch[0]=='P') { scanf("%d",&m); push(m); } else if(ch[0]=='O') { if(is_empty()) continue; else pop(); } } printf("\n"); } else if(count==0) break; } return 0; }
2.2 POJ 1028
题目大意:有两个栈,backward和forward,BACK,FORWARD 和 VISIT命令引起两个栈的push、pop操作,输出相应的结果。
实际上,可以把backward栈的top看作是current page,接下来问题迎刃而解了。
源代码:
1028 | Accepted | 184K | 32MS | C++ | 906B | 2013-08-28 16:32:02 |
#include <iostream> #include <stack> #include <string> using namespace std; int main() { string str1,str2; stack<string>forward; stack<string>backward; backward.push("http://www.acm.org/"); while(cin>>str1&&str1!="QUIT") { if(str1=="BACK") { str2=backward.top(); //the top of backward stack is the current page backward.pop(); if(backward.empty()) { cout<<"Ignored\n"; backward.push(str2); } else { cout<<backward.top()<<endl; forward.push(str2); } } else if(str1=="FORWARD") { if(forward.empty()) cout<<"Ignored\n"; else { cout<<forward.top()<<endl; backward.push(forward.top()); forward.pop(); } } else if(str1=="VISIT") { cin>>str2; backward.push(str2); while(!forward.empty()) forward.pop(); cout<<str2<<endl; } } return 0; }
2.3 POJ 1363
题目大意:元素1,2,...,N依次入栈,输入一组序列,判定其是否为出栈序列。
思路:用poping表示输出的元素序列,
(1)push元素1,N依次入栈,在每一次push操作后,判定栈顶元素==poping[ j ];若相等,栈顶元素出栈,j++ ;
(2)push操作完成之后,若所有栈为空,则说明所有元素出栈,此序列即为出栈序列;反之,则否。
在语句while(!st.empty()&&st.top()==poping[j]&&j<n)中少加一个判定条件 !st.empty() ,一直得不到正确结果。考虑循环结束条件时,一定要周到。
源代码:
1363 | Accepted | 140K | 63MS | C++ | 657B | 2013-08-28 14:10:53 |
#include <iostream> #include <stack> using namespace std; #define MAX 1000 int main() { stack<int>st; int poping[MAX]; int i,j,n; while(scanf("%d",&n)&&n!=0) { while(scanf("%d",&poping[0])&&poping[0]!=0) { for(i=1;i<n;i++) //input the poping sequence scanf("%d",&poping[i]); while(!st.empty()) //clear the stack st.pop(); for(i=1,j=0;i<=n;i++) { st.push(i); while(!st.empty()&&st.top()==poping[j]&&j<n) { st.pop(); j++; } } if(st.empty()) printf("Yes\n"); else printf("No\n"); } printf("\n"); } return 0; }
2.4 POJ 2082
题目大意在这篇文章中描述得非常清楚:有n个相邻的矩形,宽和高已知,求出能够组合形成新矩形的最大面积。
思路:用一个栈存储矩形,栈中保持矩形的高递增,cur表示刚输入的矩形,lasth表示栈顶元素的高(其实也不是,有点不好表达),curarea表示合并后的矩形的面积,maxarea表示最大矩形的面积
(1)若cur.h>=lasth,cur入栈;
(2)若cur.h<lasth,高比cur.h小的矩形出栈;在每一次出栈的过程中,进行合并操作(即合并成新矩形);由于maxarea可能出现在每一次出栈过程中,所以每一次循环都得对maxarea进行更新;
(3)置lasth=cur.h;
(4)栈可能不为空,还需要做出栈处理,操作跟(2)相类似。
源代码:
2082 | Accepted | 128K | 125MS | C++ | 861B | 2013-08-28 21:28:30 |
#include <iostream> #include <stack> using namespace std; struct Rectangle { int w,h; }; stack<Rectangle>st; int main() { int i,n,lasth,totalw,curarea,maxarea; Rectangle cur; while(scanf("%d",&n)&&n!=-1) { lasth=0; maxarea=0; for(i=0;i<n;i++) { scanf("%d%d",&cur.w,&cur.h); /*push stack*/ if(cur.h>=lasth) st.push(cur); else { totalw=0; while(!st.empty()&&st.top().h>=cur.h) { totalw+=st.top().w; curarea=totalw*st.top().h; if(curarea>maxarea) maxarea=curarea; st.pop(); } totalw+=cur.w; cur.w=totalw; st.push(cur); } lasth=cur.h; } for(totalw=0;!st.empty();st.pop()) { totalw+=st.top().w; curarea=totalw*st.top().h; if(curarea>maxarea) maxarea=curarea; } printf("%d\n",maxarea); } return 0; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。