这次的3道题目是关于栈的(都是简单的题目,难的我也不会)
题目目录:
No.1 P1165 日志分析
No.2 P1449 后缀表达式
No.3 B3614 【模板】栈
OK,开始正文!
第一道:P1165 日志分析
题目描述
M 海运公司最近要对旗下仓库的货物进出情况进行统计。目前他们所拥有的唯一记录就是一个记录集装箱进出情况的日志。该日志记录了两类操作:第一类操作为集装箱入库操作,以及该次入库的集装箱重量;第二类操作为集装箱的出库操作。这些记录都严格按时间顺序排列。集装箱入库和出库的规则为先进后出,即每次出库操作出库的集装箱为当前在仓库里所有集装箱中最晚入库的集装箱。
出于分析目的,分析人员在日志中随机插入了若干第三类操作――查询操作。分析日志时,每遇到一次查询操作,都要报告出当前仓库中最大集装箱的重量。
输入格式
包含 N+1 行:
第一行为一个正整数 N,对应于日志内所含操作的总数。
接下来的 N 行,分别属于以下三种格式之一:
- 格式 1:
0 X
,表示一次集装箱入库操作,正整数 X 表示该次入库的集装箱的重量。 - 格式 2:
1
,表示一次集装箱出库操作,(就当时而言)最后入库的集装箱出库。 - 格式 3:
2
,表示一次查询操作,要求分析程序输出当前仓库内最大集装箱的重量。
当仓库为空时你应该忽略出库操作,当仓库为空查询时你应该输出 00。
输出格式
输出行数等于日志中查询操作的次数。每行为一个整数,表示查询结果。
输入输出样例
输入 #1
13 0 1 0 2 2 0 4 0 2 2 1 2 1 1 2 1 2
输出 #1
2 4 4 1 0
说明/提示
数据范围及约定
- 对于 20% 的数据,有 N≤10;
- 对于 40% 的数据,有 N≤1000;
- 对于 100% 的数据,有 1≤N≤200000,1≤X≤10^8。
思路:
定义一个栈S1存栈里面的元素,S2存最大值
AC代码:
#include <bits/stdc++.h>
using namespace std;
stack<int>s1,s2;
signed main()
{
int n;
cin >> n;
while(n--)
{
int num;
cin >> num;
if(num==0)
{
int x;
cin >> x;
s1.push(x);
if(s2.empty()||x>=s2.top())
{
s2.push(x);
}
}
else if(num==1)
{
if(!s1.empty())
{
if(s1.top()==s2.top())
{
s2.pop();
}
s1.pop();
}
}
else
{
if(!s2.empty())
{
cout<<s2.top()<<endl;
}
else
{
cout<<"0\n";
}
}
}
return 0;
}
第二道:P1449 后缀表达式
题目描述
所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级)。
本题中运算符仅包含 +-*/。保证对于 / 运算除数不为 0。特别地,其中 / 运算的结果需要向 0 取整(即与 C++ /
运算的规则一致)。
如:3*(5-2)+7 对应的后缀表达式为:3.5.2.-*7.+@。在该式中,@
为表达式的结束符号。.
为操作数的结束符号。
输入格式
输入一行一个字符串 s,表示后缀表达式。
输出格式
输出一个整数,表示表达式的值。
输入输出样例
输入 #1
3.5.2.-*7.+@
输出 #1
16
输入 #2
10.28.30./*7.-@
输出 #2复制
-7
说明/提示
数据保证,1≤∣s∣≤50,答案和计算过程中的每一个值的绝对值不超过 10^9。
思路:
用栈做,很轻松
AC代码:
#include <bits/stdc++.h>
using namespace std;
stack<int>s;
signed main()
{
int num=0;
char c;
string a;
cin >> a;
for(int i=0;i<a.size();i++)
{
if(a[i]>='0'&&c<='9')
{
num=num*10+a[i]-'0';
}
else if(a[i]=='.')
{
s.push(num);
num=0;
}
else
{
int n1=s.top();
s.pop();
int n2=s.top();
s.pop();
if(a[i]=='+')
{
s.push(n2+n1);
}
else if(a[i]=='-')
{
s.push(n2-n1);
}
else if(a[i]=='*')
{
s.push(n2*n1);
}
else if(a[i]=='/')
{
s.push(n2/n1);
}
}
}
cout<<s.top();
return 0;
}
第三道:B3614 【模板】栈
题目描述
请你实现一个栈(stack),支持如下操作:
push(x)
:向栈中加入一个数 xx。pop()
:将栈顶弹出。如果此时栈为空则不进行弹出操作,输出Empty
。query()
:输出栈顶元素,如果此时栈为空则输出Anguei!
。size()
:输出此时栈内元素个数。
输入格式
本题单测试点内有多组数据。
输入第一行是一个整数 T,表示数据组数。对于每组数据,格式如下:
每组数据第一行是一个整数,表示操作的次数 n。
接下来 n 行,每行首先由一个字符串,为 push
,pop
,query
和 size
之一。若为 push
,则其后有一个整数 x,表示要被加入的数,x 和字符串之间用空格隔开;若不是 push
,则本行没有其它内容。
输出格式
对于每组数据,按照「题目描述」中的要求依次输出。每次输出占一行。
输入输出样例
输入 #1
2 5 push 2 query size pop query 3 pop query size
输出 #1
2 1 Anguei! Empty Anguei! 0
说明/提示
样例 1 解释
对于第二组数据,始终为空,所以 pop
和 query
均需要输出对应字符串。栈的 size 为 0。
数据规模与约定
对于全部的测试点,保证 1≤T,n≤10^6,且单个测试点内的 n 之和不超过 10^6,即 ∑n≤10^6。保证 0≤x<2^64。
提示
- 请注意大量数据读入对程序效率造成的影响。
- 因为一开始数据造错了,请注意输出的
Empty
不含叹号,Anguei!
含有叹号。
思路:
当然是——用栈模拟,注意这题有几个坑:
1.看数据范围!!!不开unsigned long long见祖宗!!!
2.每次要清空栈!!!
AC代码:
#include <bits/stdc++.h>
using namespace std;
signed main()
{
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
stack<unsigned long long>s;
while(n--)
{
string sss;
cin >> sss;
if(sss=="push")
{
unsigned long long x;
cin >> x;
s.push(x);
}
else if(sss=="pop")
{
if(!s.empty())
{
s.pop();
}
else
{
cout<<"Empty\n";
}
}
else if(sss=="query")
{
if(!s.empty())
{
cout<<s.top()<<endl;
}
else
{
cout<<"Anguei!\n";
}
}
else
{
cout<<s.size()<<endl;
}
}
}
return 0;
}
额......大家有没有发现——可能还有人不知道啥是栈......没事,我们下期讲!