【蓝桥杯2025备赛】栈和单调栈

  • 栈(伪代码)
#include<bits/stdc++.h>
using namespace std;
const int N=10010;
int stk[N],tt;

//插入
stk[++tt]=x;

//删除
tt--;

//判断是否为空
if(tt>0) not empty;
else empty;

【模板】栈

题目描述

请你实现一个栈(stack),支持如下操作:

  • push(x):向栈中加入一个数 x x x
  • pop():将栈顶弹出。如果此时栈为空则不进行弹出操作,输出 Empty
  • query():输出栈顶元素,如果此时栈为空则输出 Anguei!
  • size():输出此时栈内元素个数。

输入格式

本题单测试点内有多组数据
输入第一行是一个整数 T T T,表示数据组数。对于每组数据,格式如下:
每组数据第一行是一个整数,表示操作的次数 n n n
接下来 n n n 行,每行首先由一个字符串,为 pushpopquerysize 之一。若为 push,则其后有一个整数 x x x,表示要被加入的数, x x x 和字符串之间用空格隔开;若不是 push,则本行没有其它内容。

输出格式

对于每组数据,按照「题目描述」中的要求依次输出。每次输出占一行。

样例 #1

在这里插入图片描述

样例输入 #1
2
5
push 2
query
size
pop
query
3
pop
query
size
样例输出 #1
2
1
Anguei!
Empty
Anguei!
0

提示

样例 1 解释

对于第二组数据,始终为空,所以 popquery 均需要输出对应字符串。栈的 size 为 0。

数据规模与约定

对于全部的测试点,保证 1 ≤ T , n ≤ 1 0 6 1 \leq T, n\leq 10^6 1T,n106,且单个测试点内的 n n n 之和不超过 1 0 6 10^6 106,即 ∑ n ≤ 1 0 6 \sum n \leq 10^6 n106。保证 0 ≤ x < 2 64 0 \leq x \lt 2^{64} 0x<264

提示
  • 请注意大量数据读入对程序效率造成的影响。

  • 因为一开始数据造错了,请注意输出的 Empty 不含叹号,Anguei! 含有叹号。

    注意两点:unsigned long long的范围是 0 0 0 2 64 − 1 2^{64}-1 2641,而long long的正数最大范围是到 2 63 − 1 2^{63}-1 2631

    二是要栈清空

#include<bits/stdc++.h>
using namespace std;
#define int unsigned long long//1.要unsigned long long,long long 会错 
const int N=1e6+5;
int x;
int tt;
int stk[N];
signed main()
{   int t;
    cin>>t;string s;
    while(t--)
    {
        int n;cin>>n;tt=0;//2.栈清空
        while(n--)
        {
            cin>>s;
            if(s=="push")
            {
                
                cin>>x;
                stk[++tt]=x;
            }
            else if(s=="query")
            {
                if(tt>0)cout<<stk[tt]<<endl;
                else printf("Anguei!\n");
            }
            else if(s=="size")
            {
                printf("%d\n",tt);
            }
            else if(s=="pop")
            {
                if(tt>0)tt--;
                else printf("Empty\n");
            }
            
        }
    }
    return 0;
}

括号配对

设表达式中允许包含3种括号:圆括号、方括号和大括号。即小括号、中括号和大括号。 编写一个算法来判断表达式中的括号是否正确配对,要求利用栈的结构实现。

输入格式:

输入一行带圆括号、方括号和大括号的字符串。

输出格式:

若匹配,输出yes。若不匹配,输出no。

输入样例:

在这里给出一组输入。例如:

([1+2])

输出样例:

在这里给出相应的输出。例如:

yes

输入样例:

在这里给出一组输入。例如:

([

输出样例:

在这里给出相应的输出。例如:

no

在这里插入图片描述

思路:

遇到“(”,“]”,"{"就入栈,遇到“)”,“]“,”}“就出栈和有符号进行比对,如果成功匹配就进行下一个,如果每个都成功的匹配,那么括号匹配就完全正确,如果中间有不匹配就break

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string str;
    getline(cin,str);int flag=0;
    char topstr;stack<char>s;
    for(int i=0;i<str.size();i++)
    {   
        topstr=str[i];
        if(topstr=='('||topstr=='['||topstr=='{')s.push(topstr);
        if(topstr==')'||topstr==']'||topstr=='}')
        {
            if(s.empty()){flag=1;break;}//这一步的作用在于如果没有"(" "[" "{"的话,栈是空的,就不可能能匹配
            else 
            {
            if((s.top()=='('&&topstr==')')||(s.top()=='['&&topstr==']')||       (s.top()=='{'&&topstr=='}'))
                {
                    s.pop();
                }
                else {flag=1;break;}
            }
        }
        
    }
    if(flag==0&&s.empty())cout<<"yes";
    else cout<<"no";
    return 0;
}

后缀表达式

题目描述

所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级)。

本题中运算符仅包含 +-*/ \texttt{+-*/} +-*/。保证对于 / \texttt{/} / 运算除数不为 0。特别地,其中 / \texttt{/} / 运算的结果需要向 0 取整(即与 C++ / 运算的规则一致)。

如: 3*(5-2)+7 \texttt{3*(5-2)+7} 3*(5-2)+7 对应的后缀表达式为: 3.5.2.-*7.+@ \texttt{3.5.2.-*7.+@} 3.5.2.-*7.+@。在该式中,@ 为表达式的结束符号。. 为操作数的结束符号。

输入格式

输入一行一个字符串 s s s,表示后缀表达式。

输出格式

输出一个整数,表示表达式的值。

样例 #1

样例输入 #1
3.5.2.-*7.+@
样例输出 #1
16

样例 #2

样例输入 #2
10.28.30./*7.-@
样例输出 #2
-7

提示

数据保证, 1 ≤ ∣ s ∣ ≤ 50 1 \leq |s| \leq 50 1s50,答案和计算过程中的每一个值的绝对值不超过 1 0 9 10^9 109

思路:

表达式分为前缀表达式,中缀表达式和后缀表达式,其中对于人类来说最容易理解的就是我们的中缀表达式,我们每天进行的加减乘除,例如这种(1+1)*(2+2),运算符在操作数中间,这种表达式要考虑符号优先级,对于电脑来说中缀表达式很复杂,难以理解,相反,对于人类难以理解的后缀表达式和前缀表达式,电脑可以很好的理解,因为可以直接遍历而不用考虑优先级

做法是遇到数字存储在数字栈中,如果遇到符号,则将数字栈中的两个数字弹出,进行运算,要注意先弹出的数字在运算时在操作符右侧,而后弹出的在左侧

计算完毕后将中间数字入栈存储,直到后面有需要的时弹出栈顶元素进行计算,遍历完成后栈顶元素即为最终结果

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    getline(cin,s);
    stack<int>num;
    char topstr;int a=0;
    for(int i=0;i<s.size();i++)
    {
        topstr=s[i];
        if(topstr=='+'||topstr=='-'||topstr=='*'||topstr=='/')
        {   
            int a1=num.top();num.pop();
            int a2=num.top();num.pop();
            if(topstr=='+')num.push(a1+a2);
            else if(topstr=='-')num.push(a2-a1);
            else if(topstr=='*')num.push(a2*a1);
            else if(topstr=='/')num.push(a2/a1);
        }
        if(topstr>='0'&&topstr<='9')
        {
            a=a*10+(topstr-'0');
        }if(topstr=='.'){num.push(a);a=0;}
    }
    cout<<num.top();
    return 0;
}

单调栈

什么是单调栈

单调栈不是一种新的栈结构,它在结构上仍然是一个普通的栈,它是栈的一种使用方式。

单调栈内的元素是单调递增或者单调递减的,有单调递增栈和单调递减栈。例如,单调递减栈从栈顶到栈底是从小到大的顺序。当一个数入栈时,与栈顶比较,若比栈顶小,则入栈;若比栈顶大,则出栈,直到这个数能入栈为止。注意,每个数都一定入栈。

[USACO09MAR]

Look Up S

题目描述

Farmer John’s N (1 <= N <= 100,000) cows, conveniently numbered 1…N, are once again standing in a row. Cow i has height H_i (1 <= H_i <= 1,000,000).

Each cow is looking to her left toward those with higher index numbers. We say that cow i ‘looks up’ to cow j if i < j and H_i < H_j. For each cow i, FJ would like to know the index of the first cow in line looked up to by cow i.

Note: about 50% of the test data will have N <= 1,000.

约翰的 N ( 1 ≤ N ≤ 1 0 5 ) N(1\le N\le10^5) N(1N105) 头奶牛站成一排,奶牛 i i i 的身高是 H i ( 1 ≤ H i ≤ 1 0 6 ) H_i(1\le H_i\le10^6) Hi(1Hi106)。现在,每只奶牛都在向右看齐。对于奶牛 i i i,如果奶牛 j j j 满足 i < j i<j i<j H i < H j H_i<H_j Hi<Hj,我们可以说奶牛 i i i 可以仰望奶牛 j j j。 求出每只奶牛离她最近的仰望对象。

Input

输入格式
  1. * Line 1: A single integer: N

* Lines 2…N+1: Line i+1 contains the single integer: H_i

1 1 1 行输入 N N N,之后每行输入一个身高 H i H_i Hi

输出格式

* Lines 1…N: Line i contains a single integer representing the smallest index of a cow up to which cow i looks. If no such cow exists, print 0.

N N N 行,按顺序每行输出一只奶牛的最近仰望对象,如果没有仰望对象,输出 0 0 0

样例 #1
样例输入 #1
6 
3 
2 
6 
1 
1 
2
样例输出 #1
3 
3 
0 
6 
6 
0
提示

FJ has six cows of heights 3, 2, 6, 1, 1, and 2.

Cows 1 and 2 both look up to cow 3; cows 4 and 5 both look up to cow 6; and cows 3 and 6 do not look up to any cow.

【输入说明】 6 6 6 头奶牛的身高分别为 3,2,6,1,1,2。

【输出说明】奶牛 #1,#2 仰望奶牛 #3,奶牛 #4,#5 仰望奶牛 #6,奶牛 #3 和 #6 没有仰望对象。

【数据规模】

对于 20 % 20\% 20% 的数据: 1 ≤ N ≤ 10 1\le N\le10 1N10

对于 50 % 50\% 50% 的数据: 1 ≤ N ≤ 1 0 3 1\le N\le10^3 1N103

对于 100 % 100\% 100% 的数据: 1 ≤ N ≤ 1 0 5 , 1 ≤ H i ≤ 1 0 6 1\le N\le10^5,1\le H_i\le10^6 1N105,1Hi106

思路:

使用两个栈,一个存储奶牛的编号,一个存储奶牛的身高,如果身高比栈顶的大,则两个栈的栈顶元素均弹出,直到为空或身高不比栈顶大为止。最后把所有身高都输入完后,如果栈内还有元素,则他们是没有仰望对象的,即为0.

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N];
int main()
{
    int n,x;cin>>n;
    stack<int>s;stack<int>t;
    for(int i=0;i<=n;)
    {
        scanf("%d",&x);i++;
        while(!s.empty()&&x>s.top()&&!t.empty())
        {
            s.pop();
            a[t.top()]=i;
            t.pop();
        }
        if(s.empty()&&t.empty()){s.push(x);t.push(i);}
        if(!s.empty()&&x<=s.top()&&!t.empty()){s.push(x);t.push(i);}
        
    }
    while(!s.empty()&&!t.empty())
    {
        s.pop();
        a[t.top()]=0;
        t.pop();
    }
    for(int i=1;i<=n;i++)cout<<a[i]<<endl;
    return 0;
}
  • 25
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值