春季集训(1)——栈和队列
来源:互联网 发布:java 线程共享对象 编辑:程序博客网 时间:2024/04/30 01:46
A
http://acm.sdut.edu.cn:8080/judge/contest/view.action?cid=17#problem/A
这个题在做的时候,给胖胖讲的时候,会出现打字的一个问题,站和栈。但是,思考一下,他们都是一样的。
思路是,新建两个数组,分别是进站序列和出站序列,此问题的是判断出站序列是否合法。
先让第一个元素进栈(请注意,是栈而不是站。我以下说的概念中,站和栈都会区分的很清楚,也请读者睁大了眼睛看);
然后判断,如果栈非空而且栈顶元素等于当前出站序列的话,就弹出当前的。它可以形象地解释为,当前火车可以出站(栈)了:因为它既不空,当前最前面的火车也符合给定的出站序列;如果栈空了或者站定元素不等于当前出站序列,让火车进来一辆(入站序列入栈);
最后判断是否可以构成合法出站序列的条件是,进站序列“指针”是否等于火车最大个数n。如果等于,即超出限制,不合法;如果没有指到,i指到了n-1,就没有具体的判断意义了,所以,标记数组凡是1,就输出in,2就输出out;
请具体参看下图,协助理解。
下面是代码:
#include<iostream>#include<stack>#define max 100using namespace std;int main(){ stack<char>s; int n,i,j,k,result[max]; char str1[max],str2[max]; while(cin>>n>>str1>>str2) { j=0,i=0,k=1; s.push(str1[0]); result[0]=1; while(i<n&&j<n) { if(s.size()&&s.top()==str2[j]) { j++; s.pop(); result[k++]=0; } else { if(i == n)break; s.push(str1[++i]); result[k++]=1; } } if(i == n) cout<<"No."<<endl; else { cout<<"Yes."<<endl; for(i=0; i<k; i++) if(result[i]) cout<<"in"<<endl; else cout<<"out"<<endl; } cout<<"FINISH"<<endl; }}
B
http://acm.sdut.edu.cn:8080/judge/contest/view.action?cid=17#problem/B
这个题目的思路也很简单,碰到左括号入栈,碰到右括号出站,碰到B就停止,看栈的大小。如果出现形如
(((()(B))))
这样的,它的过程仍然合适。因为空盒子最内层的那个(),只是会被进入又弹出,所以并不影响整体的值。
下面是代码:
#include <iostream>#include <cstring>#include <stack>using namespace std;#define N 1005int main(){ char a[N]; stack<char> s; while(cin>>a) { int len = strlen(a); for(int i=0; i < len; i++) { if(a[i] == 'B') { cout<<s.size()<<endl; break; } if(a[i] == '(') s.push(a[i]); if(a[i] == ')') s.pop(); } while(!s.empty()) { s.pop(); } }}
C
http://acm.sdut.edu.cn:8080/judge/contest/view.action?cid=17#problem/C
这个题直接贴代码了,用的A题的,所以时间长了。
下面是代码:
#include <iostream>#include <stack>using namespace std;int main(){ int t; int out[1010]; int in[1010]; while(cin>>t && t) { stack<int> s; while(cin>>out[0]&&out[0]) { for(int i = 1; i < t; i++) { cin>>out[i]; } for(int i = 0; i < t; i++) { in[i] = i + 1; } int i = 0, j = 0; s.push(in[0]); while(i < t && j < t) { if(s.size()&&s.top()==out[j]) { j++; s.pop(); } else { if(i == t)break; s.push(in[++i]); } } if(i == t) cout<<"No"<<endl; else { cout<<"Yes"<<endl; } } cout<<endl; }}
D
http://acm.sdut.edu.cn:8080/judge/contest/view.action?cid=17#problem/D
D题大概意思是,求一个序列,第1次把上面的1张牌放到底部,然后最上面的牌就是1,然后拿走1。第2次把上面的2张牌依次放到底部,然后最上面的牌就是2,然后拿走2....重复这个过程,直到所有的牌都被拿走。问一开始的牌应该从上到下怎么放,才能完成这个魔术。
题意明白了,就很好模拟了。
请参考源代码:
#include<iostream>#include<queue>using namespace std;queue<int> que;void output(){ int tmp = que.front(); que.pop(); if(!que.empty()) output(); cout << tmp << ' ';}int main(){ int t, n, cnt; cin >> t; while(t--) { cin >> n; while(n) { que.push(n); cnt = n--; while(cnt--) { int tmp = que.front(); que.pop(); que.push(tmp); } } output(); cout << endl; }}
E
http://acm.sdut.edu.cn:8080/judge/contest/view.action?cid=17#problem/E
这个题思想实在是太没难度了
下面是代码:
#include <iostream>#include <stack>#include <queue>#include <string>using namespace std;int main(){ int t; cin>>t; while(t--) { int n; string type; cin>>n>>type; string command; int temp; if(type == "FIFO") { queue<int> que; while(n--) { cin>>command; if(command == "IN") { cin>>temp; que.push(temp); } else { que.empty() ? cout<<"None"<<endl : cout<<que.front()<<endl, que.pop(); } } } else { stack<int> stk; while(n--) { cin>>command; if(command == "IN") { cin>>temp; stk.push(temp); } else { stk.empty() ? cout<<"None"<<endl : cout<<stk.top()<<endl, stk.pop(); } } } }}
- 春季集训(1)——栈和队列
- 2016春季训练——搜索和优先队列
- 寒假集训第三天——栈和队列
- 寒假集训作业(3)——栈与队列
- **ACM集训day12——bfs队列
- 2016春季学习(1)——递推
- 陕西省集训(单调队列)
- 2016春季练习——曼哈顿和的问题
- 2016春季练习——优先队列的一个神奇用法
- ACM暑期集训——专题一[优先队列]
- 2016春季学习(2)——递推
- 9.3栈和队列(六)——队列
- 2016春季学习——模拟
- 2016春季学习——递推
- 2016春季训练——哈希
- 2016春季训练——树状数组
- 2016春季训练——贪心
- 2016春季练习——贪心
- 程序实现多国语言的动态切换解决方案(转)
- SQL 学习笔记3
- 基于Repo和Git的版本管理
- Oracle RAC 添加和删除OCR(10g)
- 跟随鼠标的时钟,外面一层是系统日期,还带旋转效果
- 春季集训(1)——栈和队列
- 输出英文字母表
- 复习数据结构之循环队列
- NOJ-1380(KMP)
- Linux环境用C编写PHP扩展
- Handler发送消息携带多个参数
- WinCE下监视设备插拔的参考代码
- Flash报表控件(FusionCharts) 使用
- c# 摄像头录像 及视频保存压缩等