使用STL实现栈
头文件:#include<stack>
定义:stack<int>a stack<node>a
a.empty() 堆栈为空则返回真
a.pop() 移除栈顶元素
a.push() 在栈顶增加元素
a.size() 返回栈中元素数目
a.top() 返回栈顶元素
题目一(Can you get AC?)
这是一道十分简单的入门题
代码加详细解析:
#include<stdio.h>
#include<stack>
#include<string.h>
using namespace std;
int main()
{
stack<char>a;
char b[7];
scanf("%s",b);
int len = strlen(b);
for (int i = 0; i < len; i++)
a.push(b[i]);
int p = 0;
while (!a.empty()) {
if (!a.empty() && a.top() == 'C') {
a.pop();
if (!a.empty() && a.top() == 'A')p = 1;
}
if(!a.empty()) a.pop();
}
if (p == 1)printf("Yes\n");
else printf("No\n");
return 0;
}
题目二(小鱼的数字游戏)
代码(太简单了,就不写注释了):
#include<stdio.h>
#include<stack>
using namespace std;
int main()
{
stack<int>a;
int p1, count = 0;
while (scanf("%d", &p1) != EOF && p1 != 0) {
a.push(p1);
count++;
}
while (count--) {
printf("%d ", a.top());
a.pop();
}
return 0;
}
题目三(P4387 【深基15.习9】验证栈序列)
题目描述
给出两个序列 pushed 和 poped 两个序列,其取值从 1 到 n(n<=100000)。已知入栈序列是pushed,如果出栈序列有可能是 poped,则输出 `Yes`,否则输出 `No`。为了防止骗分,每个测试点有多组数据。
输入格式
第一行一个整数 q,询问次数。
接下来 q 个询问,对于每个询问:
第一行一个整数 n 表示序列长度;
第二行 n个整数表示入栈序列;
第三行 n 个整数表示出栈序列;
输出格式
对于每个询问输出答案。
样例输入
2
5
1 2 3 4 5
5 4 3 2 1
4
1 2 3 4
2 4 1 3
样例输出
Yes
No
思路:
这题的思路并没有想象中的那么简单,以第1个例子为例,输入5个数12345,题目的意思是说入栈的顺序是12345,但并没有说出栈的顺序一定是54321。而是你输入一个一个之后,也可以直接把它弹出去再输入,然后再弹再输入也可以。比如先输入123,再弹321再输入45再弹。这样弹出顺序就变成了32154。所以,输入的顺序是12345,但是弹出的顺序就不一定是54321,可以是其他的方式。题目的意思是说问有没有54321这种输出的方式,如果有的话就是yes,如果没有就是no。这个时候我们再来看第2个样例,它是1234的输入顺序。他想要出栈的顺序是2413,那么我们就可以先输入12,然后再把2弹出来。这个时候你再输入,因为他是要弹出4,再输入34之后他会把4弹出来,这个时候想要他再弹出1,但是实际上栈里面的数字是13了,那只能先弹3再弹1,那就不可能实现这个结果,所以他就是No。
#include<stdio.h>//使用了c++的stl
#include<stack>
using namespace std;
stack<int>g;
int main()
{
int n, m;
scanf("%d", &n);
while (n--) {//多组输入
int i;
int a[100100] = { 0 };
int b[100100] = { 0 };
scanf("%d", &m);//入栈元素个数
for (i = 1; i <= m; i++)scanf("%d", &a[i]);
for (i = 1; i <= m; i++)scanf("%d", &b[i]);
int pos = 1;
for (i = 1; i <= m; i++) {
g.push(a[i]);//入栈
while (!g.empty() && g.top() == b[pos]) {//按指定顺序出栈
g.pop();
pos++;
}
}
if (g.empty()) printf("Yes\n");//如果栈内没有值,就说明有这种情况
else printf("No\n");
while (!g.empty())g.pop();//清空栈
}
return 0;
}
题目四(P5788 【模板】单调栈)
题目
注意不要时间超限了。
这是我第一次写的,时间超限了。
#include<stdio.h>
int a[3000050];
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
for (int i = 1; i <= n; i++) {
int f = 0;
for (int j = i; j <n; j++) {
if (a[i] < a[j]) {
printf("%d ", j);
f = 1;
break;
}
}
if (f == 0)printf("0 ");
}
return 0;
}
用栈来写
#include<stdio.h>
#include<stack>
int a[4000005], b[4000005];
using namespace std;
int main()
{
stack<int>g;//构建栈
int n;//输入元素个数
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);//输入元素
}
for (int i = n; i >= 1; i--)
{
while (!g.empty() && a[g.top()] <= a[i])
{
g.pop();
}
if (g.empty())
{
b[i] = 0;
}
else {
b[i] = g.top();
}
g.push(i);
}
for (int i = 1; i <= n; i++)
{
printf("%d ", b[i]);
}
return 0;
}
题目五(日志分析)
额外补充(在代码中会遇到的知识点):
哈,这其实是我第一次写时用到的,但是提交的答案错误了。
1.
exit
函数会终止程序的执行,并返回一个状态码给操作系统。这个状态码可以用来指示程序是正常结束还是遇到了错误。在 exit(1)
中,数字 1
通常表示一个错误状态。不同的数字可以表示不同类型的错误,这取决于特定的应用程序或上下文。例如,0
通常表示成功,而非零值(如 1
)表示某种类型的错误。
实例:
#include <stdlib.h> // for exit()
int main() {
// ... 其他代码 ...
if (some_error_condition) {
// 如果遇到错误条件,退出程序并返回错误码1
exit(1);
}
// ... 其他代码 ...
return 0; // 正常退出,返回状态码0
}
辅助栈
要判断栈内的最大值,可以使用一个辅助栈。具体步骤如下:
- 创建一个空栈用于存储最大值。
- 遍历主栈中的每个元素,将其压入辅助栈中。
- 在压入辅助栈之前,检查当前元素是否大于辅助栈的栈顶元素。如果是,则将辅助栈的栈顶元素弹出,直到辅助栈的栈顶元素小于或等于当前元素,然后将当前元素压入辅助栈中。
- 遍历完主栈后,辅助栈中的栈顶元素即为主栈中的最大值
思路:日志分析这道题题目挺简单的,就是三个条件,入栈出栈和查找。入栈的话,在入栈的同时还要找到最大值存入到另外一个栈里面。所以出栈的话,a栈和b栈应该是一起出站的。最后就是查找。
代码:
#include<stdio.h>
#include<stack>
using namespace std;
int main()
{
stack<int>a,b;
int n;
scanf("%d", &n);
while (n--) {
int x, y;
scanf("%d", &x);//x对应的是三种条件
if (x == 0) {
scanf("%d", &y);
a.push(y);//a入栈
if (b.empty() || a.top() > b.top())b.push(a.top());//找最大值
else b.push(b.top());//b入栈
}
if (x == 1) {//出栈
a.pop();
b.pop();
}
if (x == 2) {//查找
if (b.empty())printf("0\n");
else {
printf("%d\n",b.top());
}
}
}
return 0;
}
题目六(表达式求值)
思路:表达式求职这道题的思路很简单,但是不知道为什么我一直没有写出来,它最主要就是把带加号的都入进去。就比如说1+3×5+2,那么这个时候1先入栈,然后呢再把3入站,后面是乘以5嘛,要是乘5的话。我们就把3再出栈出栈之后再把3×5这个整体一起入栈。入栈之后我们再看后面是加2就直接把2再入栈,最后再把栈内所有的元素相加就可以了。
代码:
#include<stdio.h>
#include<string.h>
char a[1200000];
int x, cnt, ans;
int g[1000000];
int solve(int x, int g) {
int ans = x * g;
ans %= 10000;
return ans;
}
int main() {
int x = 0, last = 1;
scanf("%s", a +1);
int t = strlen(a +1);
for (int i = 1; i <= t; i++) {
if (a[i] >= '0' && a[i] <= '9') {
x = x * 10 + a[i] - '0';
x = x % 10000;
if (i == t) {
g[++cnt] = solve(x, last);
}
}
else if (a[i] == '+') {
g[++cnt] = solve(x, last);
last = 1;
x = 0;
}
else {
last = solve(x, last);
x = 0;
}
}
for (int i = 1; i <= cnt; i++) {
ans = ans + g[i];
if (ans >= 10000)ans -= 10000;
}
printf("%d\n", ans);
return 0;
}