王道机试C++第 5 章 数据结构三:栈Stack和22年蓝桥杯省赛选择题Day33

news2024/11/25 20:55:57

5.3

和队列一样,栈( Stack )也是一种线性序列结构,其存放的元素也是按照线性逻辑次序排列的。然而,与一般的线性结构相比,栈的操作仅限于逻辑上特定的一端,即新元素只能从栈的一端插入也只能从这一端删除已有的元素。
禁止操作的一端称为盲端。栈中允许元素插入和删除的一端称为栈顶,禁止操作的盲端就称为栈底。于是,插入元素和删除元素就分别称为入栈和出栈。栈中各个元素的操作次序必定遵守所谓的后进先出(Last-In First-Out, LIFO )规则,即越后入栈的元素将会越早出栈,越先入栈的元素将会越晚出栈。

1STL-stack

(1 stack 的定义
要使用 stack 的标准模板,需要在代码中添加头文件,格式为 #include <stack> 。定义一个栈 stack 的写法是 stack<typename> name ,其中 typename 是栈元素的类型,它可以是任意数据类型,name 是所定义栈的名字。
2 stack 的状态
stack 中常用作判断的状态有两个:一个是返回当前栈是否为空的 empty() ,另一个是返回当前栈元素个数的 size()
3 stack 元素的添加或删除
定义一个栈后,要向栈中添加新元素或删除已有的元素,可使用函数 push() pop()
4 stack 元素的访问
只能用 top() 来访问栈顶元素,而不像队列那样可以访问队头和队尾。
基本代码
#include <bits/stdc++.h>
using namespace std;

int main() {  
    stack<int> myStack; // 定义一个整型栈  
  
    // 输出栈的初始大小  
    cout << "The size of myStack: " << myStack.size() << endl;  
  
    // 将0到9的整数压入栈中  
    for (int i = 0; i < 10; ++i) {  
        myStack.push(i);  
    }  
    // 输出栈顶元素  
    cout << "The top of myStack: " << myStack.top() << endl;  
  
    // 输出栈的大小  
    cout << "The size of myStack: " << myStack.size() << endl;  
  
    int sum = 0; // 定义一个变量用于累加栈中元素的值  
  
    // 当栈不为空时,循环执行以下操作  
    while (!myStack.empty()) {  
        // 将栈顶元素的值加到sum中  
        sum += myStack.top();  
        // 弹出栈顶元素  
        myStack.pop();  
    }  
  
    // 输出累加结果  
    cout << "Sum: " << sum << endl;  
  
    // 检查栈是否为空,并输出信息  
    if (myStack.empty()) {  
        cout << "myStack is empty" << endl;  
    }  
  
    return 0;  
}

2.栈的应用

1 )逆序输出
栈的用途很多,最经典的用途是求解逆序输出问题。逆序输出问题有一个明显的特点,即问题的解需要以线性序列的方式给出。然而,线性序列是逆序计算并输出的,并且这类问题的规模有时不确定,难以事先知道存放数据的容器的大小。由于这类问题既有“后进先出”的特点,又在容量方面具有自适应性,而栈完美地符合了这两个特点,因此栈非常适合于求解这类问题。
例:零复杂度转置
题目描述

你会得到一个整数序列。序列的零复杂度转置与此序列相反。您的任务是编写一个程序来打印给定序列的零复杂性转置。

输入描述:对于每种情况,输入文件的第一行都包含序列的一个整数 n 长度(0 < n ≤ 10 000)。第二行包含 n 个整数数字-a1、a2、...、an (-1 000 000 000 000 000 ≤ ai ≤ 1 000 000 000 000 000)。

输出描述:对于每种情况,在输出文件的第一行上以相反的顺序打印序列。

思路提示:看到了转置就要想到用栈因为它后进先出的特性;注意这道题的数据比较大,所以需要用到long long的数据类型。以及longlong的scanf输入是%lld

代码表示
#include <bits/stdc++.h>  
using namespace std;  
  
stack<long long> sequence; // 定义一个长整型栈   
int main() {  
    int n;  
    // 循环读取输入直到文件结束  
    while (scanf("%d", &n) != EOF) {  
        // 循环n次  
        while (n--) {  
            long long number;  
            // 读取一个长整型数 long long类型 
            scanf("%lld", &number);  
            // 将数压入栈中  
            sequence.push(number);  
        }           
        // 当栈不为空时,循环执行以下操作  
        while (!sequence.empty()) {  
            // 输出栈顶元素  
            printf("%lld ", sequence.top());  
            // 弹出栈顶元素  
            sequence.pop();  
        }  
        printf("\n");  
    }     
    return 0;  
}

例:括号匹配问题
题目描述:
在某个字符串(长度不超过 100 )中有左括号、右括号和大小写字母;规定(与常见的算数式子
一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法
匹配的左括号和右括号,输出原来的字符串,并在下一行标出不能匹配的括号。不能匹配的左括
号用 "$" 标注,不能匹配的右括号用 "?" 标注。
输入: 输入包括多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过 100
输出对每组输出数据,输出两行,第一行包含原始输入字符,第二行由"$""?"和空格组成,"$"和"?" 表示与之对应的左括号和右括号不能匹配。
样例输入:
)(rttyy())sss)(
样例输出:
)(rttyy())sss)(
?               ?$
代码表示:
#include <bits/stdc++.h>
using namespace std;

int main() {
    char buf[200];
    //从标准输入中读取一行文本并将其存储在buf中
    while (fgets(buf, 200, stdin) != NULL) {
        // fgets配合while实现不确定数量的多行读取
        string str = buf;
        str.pop_back(); //移除字符串str的最后一个字符

        stack<unsigned> indexStack; // 存储左圆括号
        string res; // 保存输出的结构

        for (unsigned i = 0; i < str.size(); ++i) {//遍历字符串str
            if (str[i] == '(') {
                indexStack.push(i);
            } 
			else if (str[i] == ')') {
                if (indexStack.empty()) {
                    res.push_back('?');
                }
				else {
                    res.push_back(' ');
                    res[indexStack.top()] = ' ';
                    indexStack.pop();
                }
            } else {
                res.push_back(' ');
            }
        }

        printf("%s\n%s\n", str.c_str(), res.c_str());
    }
    return 0;
}
心得体会:

1、res.push_back(' '):在结果字符串res中添加一个空格字符,用于分隔不匹配的右圆括号和匹配的左圆括号。

2、res[indexStack.top()] = ' ':将栈顶元素对应的左圆括号位置设为空格,表示该左圆括号已经找到了匹配的右圆括号。

3、indexStack.pop():从栈indexStack中弹出栈顶元素,表示匹配的左圆括号已经处理完毕。

4、str.c_str()res.c_str()是C++字符串类(std::string)提供的成员函数,用于返回字符串的C风格字符数组表示。

  • str.c_str():返回一个指向以null结尾的字符数组,其中包含str字符串的内容。这个字符数组可以被传递给需要以C风格字符串作为参数的函数或输出流。
  • res.c_str():返回一个指向以null结尾的字符数组,其中包含res字符串的内容。

在给定的上下文中,printf函数是一个C语言的输出函数,它需要以C风格的字符串作为参数。因此,str.c_str()res.c_str()被用作printf函数的参数,以便将字符串内容传递给printf函数进行格式化输出。

5、fgets是一个C语言的函数,用于从输入流中读取一行文本并将其存储到指定的字符数组中。

函数原型如下:

char* fgets(char* str, int num, FILE* stream);

参数说明:

  • str:指向字符数组的指针,用于存储读取的文本。
  • num:要读取的字符的最大数量(包括空字符)。
  • stream:要从中读取文本的输入流。通常使用stdin表示标准输入流。

PS:fgets(buf, 200, stdin)的作用是从标准输入中读取一行文本,并将其存储到字符数组buf中,最多读取200个字符(包括换行符)。


22年蓝桥杯题

22年砍竹子

题目描述

这天,小明在砍竹子,他面前有 n 棵竹子排成一排,一开始第 i 棵竹子的高度为hi​,他觉得一棵一棵砍太慢了,决定使用魔法来砍竹子。魔法可以对连续的一段相同高度的竹子使用,假设这一段竹子的高度为 H,那么使用一次魔法可以把这一段竹子的高度都变为 其中⌊x⌋ 表示对 x 向下取整。小明想知道他最少使用多少次魔法可以让所有的竹子的高度都变为 1。

输入格式

第一行为一个正整数 n,表示竹子的棵数。

第二行共 n 个空格分开的正整数 hi​,表示每棵竹子的高度。

输出格式

一个整数表示答案

代码表示
#include <bits/stdc++.h>
using namespace std;

typedef long long LL; //将long long类型重命名为 LL
const int M=200010,N=10; //定义常量 M行和 N列 
LL arr[M][N]; //定义二维数组存储每个竹子经过魔法变化后的高度

int main() {
    int n; // 声明变量 n
    cin >> n; // 从标准输入读取 n 的值
    
//sta(用于存储每个竹子高度段的栈)、top(表示当前竹子高度段的数量)
//mx(记录所有竹子高度段的最大数量)、cnt(记录所有竹子经过魔法变化的总次数) 
    LL sta[10], top=0, mx=0, cnt=0; 
    for (int i = 0; i < n; i++) {
        top = 0; 
        LL p; 
        cin >> p; // 从标准输入读取 p 的值
        while (p > 1) {
            sta[top++] = p; //将当前竹子的高度p存入栈sta中,并将top加1
            p = sqrt(p/2 + 1); 
        }
        mx = max(mx, top); // 更新 mx 的值为 mx 和 top 中的较大值,竹子高度段的最大数量
        cnt += top; // 将 top 的值累加到 cnt 上
        
//循环遍历当前竹子的高度段,同时使用两个变量j和k,k从高度段的末尾开始,j从0开始
        for (int j = 0, k = top - 1; k >= 0; j++, k--) {
            arr[i][j] = sta[k]; // 将 sta数组中的元素逆序存入 arr[i] 数组中
        }
    }
    for (int i = 0; i < mx; i++) {
        for (int j = 1; j < n; j++) {
            if (arr[j][i] == arr[j-1][i] && arr[j-1][i]) {
                cnt--; //不需要额外的魔法次数
        }
    }
    cout << cnt << endl; // 将 cnt 的值输出到标准输出

    return 0;
}
心得体会

代码的主要逻辑如下:

1、从输入中读取竹子的数量n

2、定义一个二维数组arr,用于存储每个竹子经过魔法变化后的高度。

3、遍历每个竹子,对于每个竹子进行如下操作:

1)初始化一个变量top为0,表示当前竹子经过魔法变化后的高度段数。

2)读取当前竹子的初始高度p

3)通过一个循环将当前竹子的高度p不断变化,直到变为1。在每次循环中,将当前高度p存入一个栈sta中,并将top加1。同时,更新高度p为⌊ sqrt(⌊p/2⌋ + 1)⌋,即将当前高度段的竹子高度经过魔法变化后的高度。

4)记录当前竹子经过魔法变化后的高度段数top的最大值mx,以及所有竹子经过魔法变化的总次数cnt

5)将栈sta中的元素逆序存入二维数组arr中,表示当前竹子的高度段经过魔法变化后的高度。

6)通过两个嵌套循环遍历每个竹子的每个高度段。如果当前竹子的高度段与上一个竹子的相同且不为0,则将cnt减1,表示这个高度段不需要额外的魔法次数。

7)输出变化的总次数cnt,即为最少需要使用的魔法次数,以使所有竹子的高度都变为1


试题 A:九进制转十进制

【问题描述】

九进制正整数 2022转换成十进制等于多少?

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

1478(进制转换就手算吧哈)


补充进制转换手算知识

1、十进制转二进制(十进制转换为X进制:给出的十进制数 ÷X;余数从下往上读得到X进制数)

除2取余倒序输出:十进制转二进制的转换原理:除以2,反向取余数,直到商为0终止。

eg: 9(10)=1001(2)

除8取余倒序输出:转换原理:除以8,反向取余数,直到商为0终止。

2、X进制转换为十进制(第一位系数*X^0+第二位系数*X^1.......)

小数:

3、二进制转换为八进制和十六进制(分别写出二进制后 三合一 和 四合一)

4、八进制、十六进制转换成二进制(八进制数的一位是二进制数的三位,十六进制数的一位是二进制数的四位)

5、八进制与十六进制之间的转换两者之间的转换

可以借助十进制或者二进制完成,可以先将八进制转换成十进制或二进制,再转换成十六进制


试题 B:顺子日期

【问题描述】

小明特别喜欢顺子。顺子指的就是连续的三个数字:123456 等。顺子日期指的就是在日期的 уyyymmdd 表示法中,存在任意连续的三位数是一个顺子的日期。例如 20220123 就是一个顺子日期,因为它出现了一个顺子:123; 而 20221023 则不是一个顺子日期,它一个顺子也没有。小明想知道在整个 2022 年份中,一共有多少个顺子日期。

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

14

找1 2 3和0 1 2组合的日期,注意与年无关了因为题目要求顺子也就是指从小到大了。

01.23;11.23;12.30;12.31;

01.21;01.22;01.23;01.24;01.25;01.26;01.27;01.28;01.29;

10.12;

经验:会做的手算题,一定要认真仔细拿到分,这道题一开始就不仔细导致考虑的不周到。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1511918.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker部署ChatGLM3、One API、FastGPT

创建并运行chatglm3容器 docker run --name chatglm3 -p 8000:8000 registry.cn-hangzhou.aliyuncs.com/ryyan/chatglm.cpp:chatglm3-q5_1 创建并运行one-api容器 (其中挂载路径 D:\one-api 可以选择你自己喜欢的目录) docker run --name oneapi -d -p 3000:3000 -e TZAsia…

FPGA高端项目:FPGA基于GS2971+GS2972架构的SDI视频收发+图像缩放,提供3套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案的SDI接收发送本方案的SDI接收纯verilog图像缩放纯verilog多路视频拼接应用本方案的SDI接收HLS图像缩放HLS多路视频拼接应用本方案的SDI接收OSD动态字符叠加输出应用本方案的SDI接收HLS多路视频融合叠加应…

服务器被大流量攻击怎么办?如何防御攻击?

随着网络的发展&#xff0c;我们所遇到的安全挑战也越来越多。尤其是近年来&#xff0c;网络攻击频发&#xff0c;许多互联网企业深受其扰。为了不影响自身业务的稳定运行&#xff0c;许多企业都在想方设法的寻求解决方案&#xff0c;防止服务器被攻击而影响业务发展。下面我们…

Java代码审计安全篇-SSRF(服务端请求伪造)漏洞

前言&#xff1a; 堕落了三个月&#xff0c;现在因为被找实习而困扰&#xff0c;着实自己能力不足&#xff0c;从今天开始 每天沉淀一点点 &#xff0c;准备秋招 加油 注意&#xff1a; 本文章参考qax的网络安全java代码审计&#xff0c;记录自己的学习过程&#xff0c;还希望各…

常见的排序算法的时间复杂度

常见的排序算法的时间复杂度 排序算法的时间复杂度通常取决于输入数据的规模&#xff08;通常表示为n&#xff09;。以下是一些常见排序算法及其平均、最好和最坏情况下的时间复杂度&#xff1a; 1、冒泡排序&#xff08;Bubble Sort&#xff09; 平均时间复杂度&#xff1a;…

使用reprepro+nginx搭建apt服务器

目录 项目背景 项目要求 项目开发过程 1、apt服务器的搭建 2、实现自定义指定源文件列表来实现apt update更新 3、实现软件启动时自动更新 4. source.list中镜像源地址的格式 项目开发的难点/坑点 总结 项目背景 前面写过一篇“利用Nginx搭建一个apt服务器”&#xff…

FreeRTOS学习笔记-基于stm32(5)列表和列表项

一、列表与列表项简介 列表是FreeRTOS中的一种数据结构&#xff0c;类似双向循环链表。用来跟踪FreeRTOS中的任务。列表项就是存放在列表中的项目。 二、列表 列表结构体&#xff1a; typedef struct xLIST {listFIRST_LIST_INTEGRITY_CHECK_VALUE //校验值c…

闲聊电脑(7)常见故障排查

闲聊电脑&#xff08;7&#xff09;常见故障排查 夜深人静&#xff0c;万籁俱寂&#xff0c;老郭趴在电脑桌上打盹&#xff0c;桌子上的小黄鸭和桌子旁的冰箱又开始窃窃私语…… 小黄鸭&#xff1a;冰箱大哥&#xff0c;平时遇到电脑故障该咋处理呢&#xff1f; 冰箱&#xf…

vscode使用svn

网上这种文章很多&#xff0c;但很多都实现不了&#xff0c;自己亲测安装有效的过程记录下来&#xff0c;分享给大家。 第一步&#xff1a;去官网下载svn.安装TortoiseSVN 下载地址 下载的地址&#xff1a; Apache Subversion Binary Packageshttps://subversion.apache.or…

55. 跳跃游戏(力扣LeetCode)

文章目录 55. 跳跃游戏贪心每一次都更新最大的步数 取最大跳跃步数&#xff08;取最大覆盖范围&#xff09; 55. 跳跃游戏 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后…

信号处理--基于Fisher分数的通道选择的多通道脑电信号情绪识别

目录 背景 亮点 环境配置 数据 方法 结果 代码获取 参考文献 背景 基于脑电的情绪分析&#xff0c;目前是当前研究的一个主要方向和热点。 亮点 使用基于Fisher score的标准来筛选具有高判别意义的脑电通道&#xff1b; 使用基于特征选择的遗传算法实现特征的筛选&#xff0c;从…

vue项目:webpack打包优化实践

本文目录 一、项目基本信息二、分析当前项目情况1、使用 webpack-bundle-analyzer 插件2、使用 speed-measure-webpack-plugin 插件 三、解决构建问题1、caniuse-lite 提示的问题2、 warning 问题 四、打包速度优化1、修改source map2、处理 loader 五、webpack性能优化1、使用…

SPI机制详解

SPI机制详解 什么是SPI机制&#xff1f; SPI&#xff1a;Service Provider Interface&#xff0c;中文直译&#xff1a;服务提供者接口&#xff0c;它通过在ClassPath路径下的META-INF/service文件夹中查找文件&#xff0c;并自动加载文件里所定义的类 在面向对象的设计原则…

Linux中文件的权限

我们首先需要明白&#xff0c;权限 用户角色 文件的权限属性 一、拥有者、所属组和other&#xff08;用户角色&#xff09; 以文件file1为例 第一个箭头所指处即是文件的拥有者&#xff0c;拥有者为zz 第二个箭头所指处即使文件的所属组&#xff0c;所属组为zz 除去拥有者…

利用高分五号02星高光谱数据进行地物识别

高分五号02星搭载了一台60公里幅宽、330谱段、30米分辨率的可见短波红外高光谱相机&#xff08;AHSI&#xff09;&#xff0c;可见近红外&#xff08;400~1000nm&#xff09;和短波红外光谱&#xff08;1000~2500nm&#xff09;分辨率分别达到5纳米和10纳米。单看参数性能优越&…

spring boot使用mybatisplus访问mysql的配置流程

网上教程大多教人新建一个带对应组件的项目&#xff0c;本文记录如何在一个已有springboot2.x项目中&#xff0c;配置使用mybatisplus来访问mysql。包括使用wrapper和自己写mapper.xml的自定义函数两种和数据库交互的方式。 关于项目的创建&#xff0c;参考创建springboot 2.x…

PFMEA的输入输出和特殊特性

DFMEA輸入&#xff1a;技术条件、市场需求 DFMEA輸出&#xff1a;产品特殊特性、试验、样件CPPFMEA輸入&#xff1a;过往经验、流程图、DPMEA PFMEA輸出&#xff1a;CP、过程特殊特性、SIP、SOP1. PFMEA的输入包括&#xff1a;&#xff08;&#xff09;过程流程图、DFMEA 、图样…

基于springboot+vue的线上教育系统(源码+论文)

目录 前言 一、功能设计 二、功能实现 三、库表设计 四、论文 前言 现在大家的生活方式正在被计算机的发展慢慢改变着&#xff0c;学习方式也逐渐由书本走向荧幕,我认为这并不是不能避免的,但说实话,现在的生活方式与以往相比有太大的改变&#xff0c;人们的娱乐方式不仅仅…

P4513 小白逛公园 习题笔记(线段树维护区间最大连续子段和)

传送门https://www.luogu.com.cn/problem/P4513本文参考了董晓老师的博客 这道题着实想了很长时间&#xff08;新手&#xff09;&#xff0c;只能想到一个O&#xff08;mn&#xff09;的dp普通写法&#xff0c;那么遇上区间修改问题改怎么操作呢。答案很明显&#xff0c;线段树…

微服务day01 -- SpringCloud01 -- (Eureka , Ribbon , Nacos)

介绍微服务 1.认识微服务(p1-p5) 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢&#xff1f; 1.0.学习目标 了解微服务架构的优缺点 1.1.单体架构 单体架构&#…