面向对象程序设计(荣誉)实验四 deque,stack,queue
Posted 上山打老虎D
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象程序设计(荣誉)实验四 deque,stack,queue相关的知识,希望对你有一定的参考价值。
目录
1.双向队列(deque)
题目描述
双向队列只能在队尾和队头做出队,入队的操作。
现在给你一系列的操作,请输出最后队列的状态。
命令格式:
LIN X X表示一个整数,命令代表队头进队操作;
RIN X 表示X队尾进队操作;
ROUT 表示队尾删除一个元素的操作,当队列为空时,命令不合法;
LOUT 表示队头删除一个元素的操作,当队列为空时,命令不合法。
输入
第一行包含一个整数M(M<=10000),表示有M个操作;
以下M行每行包含一条命令;
命令可能不合法,对于不合法的命令,请在输出中处理
输出
输出的第一行包含队列进行了M次操作后的状态,从左往右输出,每两个之间用空格隔开,最后也有空格;若队列为空,输出EMPTY。
以下若干行处理不合法的命令(如果存在);
对于每一条不合法的命令,请输出一行X ERROR
其中X表示是第几条命令
样例输入
8
LIN 5
RIN 6
LIN 3
LOUT
ROUT
ROUT
ROUT
LIN 3
样例输出
3
7 ERROR
题解
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
deque<int> q;
vector<int> error;
int main(){
int m;
cin >> m;
for(int i = 1; i <= m; i++){
string op;int num;
cin >> op;
if(op == "LIN"){
cin >> num;
q.push_front(num);
}
if(op == "RIN"){
cin >> num;
q.push_back(num);
}
if(op == "ROUT"){
if(q.empty()){
error.push_back(i);
continue;
}
q.pop_front();
}
if(op == "LOUT"){
if(q.empty()){
error.push_back(i);
continue;
}
q.pop_back();
}
}
if(q.size() == 0){
puts("EMPTY");
}else{
for(int i = 0; i < q.size(); i++){
cout<<q[i]<<" ";
}cout<<endl;
}
if(error.size()){
for(int i = 0; i < error.size(); i++){
cout<<error[i]<<" ERROR\\n";
}
}
}
2.括号匹配(stack)
题目描述
给定一个表达式e,包含各种字符,如字母、数字、运算符、标点、空格和括号()[]{}等, 判断其中括号是否匹配,如是,则返回0, 否则根据错误类型返回1-3:
错误类型包括1、2、3类型:
类型1:
左右括号不匹配,如"(]", “(((]))))”, “((}”,“let {x=a[0)*(b+c); y=b}”
类型2:
发现有左括号不存在与之匹配的右括号,有多余的左括号,如"(", “(([]”, “()(()"
类型3:
发现右括号不存在与之匹配的左括号,有多余的右括号,如")", “())”,"(())”。
输入
第一行输入测试次数
第二行开始输入字符串
输出
如果成功匹配则输出yes
如果不成功则输出no,然后输出类型
样例输入
3
()
(]
(([]
样例输出
yes
no 1
no 2
题解
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
string str;
int main(){
int t;
cin >>t;
while(t--){
stack<int> s;
cin >> str;
int flag = 0;
int i;
for(i = 0; i < str.size(); i++){
if(str[i] == '('||str[i] == '['||str[i]=='{'){
s.push(str[i]);
}
if(str[i] == ')'||str[i] == ']'||str[i]=='}'){
if(s.size() == 0){
flag = 3;
break;
}
char t = s.top();
if(str[i] == ')' && t == '('){
s.pop();continue;
}
if(str[i] == ']' && t == '['){
s.pop();continue;
}
if(str[i] == '}' && t == '{'){
s.pop();continue;
}
flag = 1;
break;
}
}
if(s.size() != 0 && flag != 1){
flag = 2;
}
if(flag) cout<<"no "<<flag<<endl;
else cout<<"yes\\n";
}
}
3.田忌赛马(deque)
题目描述
田忌和大王赛马。每人分别有n匹马。给出所有马的速度,田忌可自行决定用第i匹与大王的第j匹马比赛。赢一场积1分, 输一次扣1分,平局得0分。田忌赛马最多能得几份?
输入
第一行输入测试次数t
每次测试首先输入每个人马的数量n。
随后两行给出马的速度,第一行为田忌马的速度,第二行为大王马的速度。假设已按速度升序排序。
输出
输出田忌最多能赢的场数。
样例输入
2
3
92 83 71
95 87 74
2
20 20
20 20
样例输出
1
0
题解
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
string str;
int main(){
int t;
cin >>t;
while(t--){
int cnt = 0, n, num, my;
deque<int> other;
cin >> n;
for(int i = 0; i < n; i++){
cin >> num;
other.push_back(num);
}
for(int i = 0; i < n; i++){
cin >> my;
if(my> other.back()){
cnt++;
other.pop_back();
}
else{
if(my < other.front()){
cnt--;
}
other.pop_front();
}
}
cout<<cnt<<endl;
}
}
4.火车站(stack)
题目描述
火车站只有一条铁路,所有的火车都停在那里。所以所有的火车都是从一边进站,从另一边出站。如果A列先进入铁路,然后B列在A列离开之前进入铁路,那么A列在B列离开之前不能离开。下图说明了问题所在。车站里最多有9列火车,所有的火车都有一个ID(编号从1到N),火车按照O1的顺序进入火车,火车是否可以按照O2的顺序驶出。
输入
输入包含几个测试用例。
每个测试用例由一个整数(列车数)和两个字符串组成。两个字符串分别为列车入站顺序和列车出站顺序。
输出
如果不能按照指定顺序出站,输出“No”。
如果可以,输出“Yes”,然后输出出入站顺序(对于进入铁路的列车,应输出“in”,对于出铁路的列车,应输出“out”)。在每个测试用例之后打印一行包含“FINISH”。
样例输入
3
3 123 321
3 abc cab
3 123 123
样例输出
Yes
in
in
in
out
out
out
FINISH
No
FINISH
Yes
in
out
in
out
in
out
FINISH
题解
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
string in,out;
int main(){
int t,n;
cin >>t;
while(t--){
int flag = 1;
cin >> n >> in >> out;
stack<char> s;
vector<string> ans;
int pos = 0, i;
for(i = 0; i < out.size() && pos < out.size(); i++){
ans.push_back("in");
s.push(in[i]);
while(s.size() && s.top() == out[pos]){
pos++;
s.pop();
ans.push_back("out");
}
}
if(pos == i && pos == out.size()){
puts("Yes");
for(int i = 0; i < ans.size();i++){
cout<<ans[i]<<endl;
}
}else puts("No");
puts("FINISH");
}
}
5.银行单队列多窗口模拟(queue)
题目描述
假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙。当有窗口空闲时,下一位顾客即去该窗口处理事务。当有多个窗口可选择时,假设顾客总是选择编号最小的窗口。
本题要求输出前来等待服务的N位顾客的平均等待时间、最长等待时间、最后完成时间。
输入
输入第1行给出正整数N(≤1000),为顾客总人数;随后N行,每行给出一位顾客的到达时间T和事务处理时间P,并且假设输入数据已经按到达时间先后排好了顺序;最后一行给出正整数K(≤10),为开设的营业窗口数。这里假设每位顾客事务被处理的最长时间为60分钟。
输出
在一行中输出平均等待时间(输出到小数点后1位)、最长等待时间、最后完成时间,之间用1个空格分隔,行末不能有多余空格。
样例输入
9
0 20
1 15
1 61
2 10
10 5
10 3
30 18
31 25
31 2
3
样例输出
6.2 17 62
题解
#include<bits/stdc++.h>
#define P pair<int,int>
using namespace std;
int endtime[15];
int k;
int getID(int start_time, int &minWait) {
minWait = 0x3f3f3f;
int id;
for (int i = 1; i <= k; i++) {
if (endtime[i] <= start_time) {
minWait = 0;
return i;
}
if (endtime[i] - start_time < minWait) {
minWait = endtime[i] - start_time;
id = i;
}
}
return id;
}
int main() {
int n, pos, time, len;
cin >> n;
queue<P > people;
for (int i = 0; i < n; i++) {
cin >> time >> len;
people.push(P(time, len));
}
cin >> k;
double sum = 0;
int maxWait = 0;
while (!people.empty()) {
P now = people.front();
people.pop();
int wait, id = getID(now.first, wait);
sum += wait;
maxWait = max(maxWait, wait);
endtime[id] = now.first + now.second + wait;
}
int last = 0;
for (int i = 1; i <= k; i++) {
last = max(last, endtime[i]);
}
printf("%.1f", sum / (1.0 * n));
cout << " " << maxWait << " " << last << endl;
}
6.六度空间(queue)
题目描述
六度空间理论指出:你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过6个中间人你就能够认识任何一个陌生人。验证这一理论需要大数据量。现在,只需要计算任意两个人通过多少个中间人能互相认识。
假设有 n 个人,他们的编号为 1~n,其中有一些人相互认识,现在 x 想通过一些中间人认识 y(如果 a 认识 b,b 认识 c,那么 a 可以通过 b 来认识 c),编程求出 x 最少需要通过多少人才能认识 y。
思路:x入队列。只有队列非空,取队头元素,队头元素为y,结束。否则,访问队头元素所在的行,他认识的人还未入对,则入队。因还有通过多少人认识,入队除元素外,加层次。x层次为0。x认识的为1,再下一次为2。
该题是从x出发,一层层找他认识的人,直到找到y,或队列空,即找不到y。
输入
第一行,测试次数t
每组测试数据格式如下:
第 1 行 3 个整数 n、x、y,2≤n≤100;
接下来的 n 行是一个 n×n 的邻接矩阵,
a[i][j]=1 表示 i 认识 j,a[i][j]=0 表示不认识。
保证 i=j 时,a[i][j]=0,并且 a[i][j]=a[j][i]。
输出
每组测试数据,输出一行,输出x 认识 y 最少需要通过的人数。如果x通过中间的人不能认识y,输出no。
样例输入
2
5 1 5
0 1 0 0 0
1 0 1 1 0
0 1 0 1 0
0 1 1 0 1
0 0 0 1 0
5 4 5
0 1 0 1 0
1 0 1 0 0
0 1 0 0 1
1 0 0 0 0
0 0 1 0 0
样例输出
2
3
题解
#include<bits/stdc++.h>
using namespace std;
int n;
int mp[105][105], dis[105];
void bfs(int s) {
dis[s] = 0;
queue<int> q;
q.push(s);
while (q.size()) {
int u = q.front();
q.pop();
for (int i = 1; i <= n; i++) {
if (mp[u][i] && dis[i] == 0) {
q.push(i);
dis[i] = dis[u] + 1;
}
}
}
}
int main() {
int t, s, to;
cin >> t;
while (t--) {
cin >> n >> s >> to;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> mp[i][j];
}
dis[i] = 0;
}
bfs(s);
if (dis[to] == 0) cout << "no" << endl;
else cout << dis[to] - 1 << endl;
}
}
以上是关于面向对象程序设计(荣誉)实验四 deque,stack,queue的主要内容,如果未能解决你的问题,请参考以下文章
面向对象程序设计(荣誉)实验六 set,bitset,multimap