CCE13.【C++ Cont】练习题组13 静态链表专题
目录
1.B3630 排队顺序
题目
分析
代码
提交结果
2.B3631 单向链表
题目
分析
前置知识:map数组加快访问速度(简单的哈希表优化)
使用map数组的重要提醒
代码
提交结果
3.★P1160 队列安排
题目
分析
方法1:带头不循环双向链表的设计
方法2:带头循环的双向链表设计
删除元素操作
带头不循环双向链表代码
提交结果
带头循环的双向链表代码
提交结果
1.B3630 排队顺序
题目
https://www.luogu.com.cn/problem/B3630
题目描述
有 n(2≤n≤10^6) 个小朋友,他们的编号分别从 1 到 n。现在他们排成了一个队伍,每个小朋友只知道他后面一位小朋友的编号。现在每个小朋友把他后面是谁告诉你了,同时你还知道排在队首的是哪位小朋友,请你从前到后输出队列中每个小朋友的编号。
输入格式
第一行一个整数 n,表示小朋友的人数。
第二行 n 个整数,其中第 i 个数表示编号为 i 的小朋友后面的人的编号。如果这个数是 0,则说明这个小朋友排在最后一个。
第三行一个整数 h,表示排在第一个的小朋友的编号。
输出格式
一行 n 个整数,表示这个队伍从前到后所有小朋友的编号,用空格隔开。
输入输出样例
输入 #1
6 4 6 0 2 3 5 1输出 #1
1 4 2 6 5 3
分析
线索:"只知道他后面一位小朋友的编号","后面"体现单向链表
本题较好考察了单链表的概念,本题没有必要创造单链表,而是直接按静态单链表去访问
代码
#include <iostream>
#include <vector>
#define endl "\n"//提高换行的运行速度
const int N=1e6+10;
using namespace std;
int main()
{std::ios::sync_with_stdio(false);std::cin.tie(0);int n, first, index;vector<int> arr(N);cin >> n;for (int i = 1; i <= n; i++){cin >> arr[i];}cin >> first;index = first;cout << first << " ";while (arr[index] != 0){cout<<arr[index]<<" ";index = arr[index];}return 0;
}
其实可以借用 文章的print函数
#include <iostream>
#include <vector>
using namespace std;
const int N=1e3+10;
int main()
{std::ios::sync_with_stdio(false);std::cin.tie(0);int n,head;vector<int> next(N);cin >> n;for (int i = 1; i <= n; i++){cin >> next[i];}cin >> head;for (int i=head;i;i=next[i]){cout<<i<<" "; } return 0;
}
提交结果
2.B3631 单向链表
题目
https://www.luogu.com.cn/problem/B3631
题目描述
实现一个数据结构,维护一张表(最初只有一个元素 1)。需要支持下面的操作,其中 x 和 yy 都是 1 到 10^6 范围内的正整数,且保证任何时间表中所有数字均不相同,操作数量不多于 10^5:
1 x y
:将元素 y 插入到 x 后面;2 x
:询问 xx 后面的元素是什么。如果 x 是最后一个元素,则输出 0;3 x
:从表中删除元素 x 后面的那个元素,不改变其他元素的先后顺序。输入格式
第一行一个整数 q 表示操作次数。
接下来 q 行,每行表示一次操作,操作具体见题目描述。
输出格式
对于每个操作 2,输出一个数字,用换行隔开。
输入输出样例
输入 #1
6 1 1 99 1 99 50 1 99 75 2 99 3 75 2 1输出 #1
75 99
分析
这道题用单链表或顺序表都能做,但是顺序表的任意位置插入和删除时间复杂度都是,运行速度慢,而借助map数组(题目提示:且保证任何时间表中所有数字均不相同)的单链表时间复杂度为
,很快!
前置知识:map数组加快访问速度(简单的哈希表优化)
一般查找链表的某个元素通常使用循环,即遍历链表,时间复杂度为,而如果借助map数组,直接访问其元素map[i],时间复杂度为
,即用空间换时间
map[i]用来标记i这个元素在链表的什么位置
例如:
map数组将e数组和对应的下标建立联系
上方链表的map数组为
map[i]==-1为链表中删除的元素,其map[i]为无效值
使用map数组的重要提醒
1.存储的数值不能过大; 2.链表中不能有相同的元素;
代码
#include <iostream>
#include <vector>
#define endl "\n"
using namespace std;
const int N=1e6+10;
class List
{public:int val[N];int next[N];int map[N];//map数组加快访问速度,map[i]用来标记i这个元素在什么位置int head;int id;List(){next[0]=1;val[1]=1;next[1]=-1;head=0;id=1;map[1]=1; }void insert(int x,int y){int pos=map[x];val[++id]=y;map[y]=id;if (next[pos]==-1){//尾插next[pos]=id;next[id]=-1;}else{//头插或者中间插入next[id]=next[pos];next[pos]=id; }}void search(int x){int pos=map[x];if (next[pos]==-1)//为尾部元素 {cout<<"0"<<endl;return;}if (map[x]!=-2)cout<<val[next[pos]]<<endl;}void erase(int x){int pos=map[x];if (next[pos]!=-1){map[val[next[pos]]]=-2;next[pos]=next[next[pos]];//非尾删}}
};int main()
{std::ios::sync_with_stdio(false);std::cin.tie(0);List list;int q,op,x,y;cin>>q;while(q--){cin>>op;if (op==1){cin>>x>>y;list.insert(x,y); } else if (op==2){cin>>x;list.search(x);}else //op==3{cin>>x;list.erase(x);}}return 0;
}
提醒:const int N=1e6+10;如果N小了会报段错误,如下图
提交结果
3.★P1160 队列安排
题目
https://www.luogu.com.cn/problem/P1160
题目描述
一个学校里老师要将班上 N 个同学排成一列,同学被编号为 1∼N,他采取如下的方法:
先将 1 号同学安排进队列,这时队列中只有他一个人;
2∼N 号同学依次入列,编号为 i 的同学入列方式为:老师指定编号为 i 的同学站在编号为 1∼(i−1) 中某位同学(即之前已经入列的同学)的左边或右边;
从队列中去掉 M 个同学,其他同学位置顺序不变。
在所有同学按照上述方法队列排列完毕后,老师想知道从左到右所有同学的编号。
输入格式
第一行一个整数 N,表示了有 N 个同学。
第 2∼N 行,第 i 行包含两个整数 k,p,其中 k 为小于 i 的正整数,p 为 0 或者 1。若 p 为 0,则表示将 i 号同学插入到 k 号同学的左边,p 为 1 则表示插入到右边。
第 N+1 行为一个整数 M,表示去掉的同学数目。
接下来 M 行,每行一个正整数 x,表示将 x 号同学从队列中移去,如果 x 号同学已经不在队列中则忽略这一条指令。
输出格式
一行,包含最多 N 个空格隔开的整数,表示了队列从左到右所有同学的编号。
输入输出样例
输入 #1
4 1 0 2 1 1 0 2 3 3输出 #1
2 4 1说明/提示
【样例解释】
将同学 2 插入至同学 1 左边,此时队列为:
2 1
将同学 3 插入至同学 2 右边,此时队列为:
2 3 1
将同学 4 插入至同学 1 左边,此时队列为:
2 3 4 1
将同学 3 从队列中移出,此时队列为:
2 4 1
同学 3 已经不在队列中,忽略最后一条指令
最终队列:
2 4 1
【数据范围】
对于 20% 的数据,1≤N≤10。
对于 40% 的数据,1≤N≤1000。
对于 100% 的数据,1<M≤N≤10^5。
分析
不要被题目迷惑,以为同学入队和出队就要使用队列,其实不然,用队列或者顺序表解的时间复杂度都为,没有链表
快
其次本题要求"若 p 为 0,则表示将 i 号同学插入到 k 号同学的左边,p 为 1 则表示插入到右边",有左有右一定用双向链表(循环或不循环)
方法1:带头不循环双向链表的设计
由于学生入队的顺序是固定的,而且从2~N,显然不用专门开数组val[]来存储学生的编号,更不需要遍历指针id,从而简化代码,只需要next[]和prev[]数组和头指针head
一开始链表只存储哨兵位和编号为1的学生
逻辑结构
(-1代表无效下标)
物理结构
上面这个表有两种看法
看法1:竖着看,相当于逻辑结构的每个节点(下标充当val数组,即节点的数据域)
看法2:横着看,为物理存储方式
方法2:带头循环的双向链表设计
删除元素操作
注意:删除某个元素x时需要用一个状态数组is_erase来看
is_erase[x]==0说明没有删除过,可以删除;删除过x后is_erase[x]==1,确保下次不再删除x
带头不循环双向链表代码
#include <iostream>
#include <vector>
using namespace std;
int main()
{std::ios::sync_with_stdio(false);std::cin.tie(0);int n,k,p,m,x;cin>>n;vector<int> next(n+1,-1);vector<int> prev(n+1,-1);vector<int> is_erase(n+1,0);//处理头结点和编号为1的学生 next[0]=1;prev[1]=0;prev[0]=-1;next[1]=-1; for (int i=2;i<=n;i++)//i既为下标又为学生的编号 {cin>>k>>p;if (p==0)//i放在k的左边 {next[i]=k;prev[i]=prev[k];next[prev[k]]=i;prev[k]=i; //因为一开始要访问到prev[k],所以最后修改prev[k] } else //p==1{if (next[k]==-1){next[k]=i;//尾插单独写prev[i]=k;}else{next[i]=next[k];prev[i]=k;prev[next[k]]=i;next[k]=i;//因为一开始要访问到next[k],所以最后修改next[k] }}}cin>>m;while(m--){cin>>x;//is_erase数组用于检查x是否被删过一次了 if (!is_erase[x]){if (next[x]==-1){//尾删单独写 next[prev[x]]=-1;}else{next[prev[x]]=next[x];prev[next[x]]=prev[x];is_erase[x]=1;} }}for (int i=next[0];i!=-1;i=next[i]){cout<<i<<" ";}return 0;
}
提交结果
带头循环的双向链表代码
#include <iostream>
#include <vector>
using namespace std;
int main()
{std::ios::sync_with_stdio(false);std::cin.tie(0);int n, k, p, m, x;cin >> n;vector<int> next(n + 1, -1);vector<int> prev(n + 1, -1);vector<int> is_erase(n + 1, 0);next[0] = 1;prev[1] = 0;prev[0] = 1;next[1] = 0;for (int i = 2; i <= n; i++)//i既为下标又为学生的编号 {cin >> k >> p;if (p == 0)//i放在k的左边 {next[i] = k;prev[i] = prev[k];next[prev[k]] = i;prev[k] = i; //因为一开始要访问到prev[k],所以最后修改prev[k] }else //p==1{prev[i] = k;next[i] = next[k];prev[next[k]] = i; //因为一开始要访问到next[k],所以最后修改next[k] next[k] = i; }}cin >> m;while (m--){cin >> x;//is_erase数组用于检查x是否被删过一次了 if (!is_erase[x]){//中间删next[prev[x]] = next[x];prev[next[x]] = prev[x];is_erase[x] = 1;}}for (int i = next[0]; i != 0; i = next[i]){cout << i << " ";}return 0;
}
p==0和p==1都可以等价为中间插入,头插和尾插不用区分
提交结果
可以看到两种方法明显方法2代码量较少,特殊情况不用单独判断
相关文章:

CCE13.【C++ Cont】练习题组13 静态链表专题
目录 1.B3630 排队顺序 题目 分析 代码 提交结果 2.B3631 单向链表 题目 分析 前置知识:map数组加快访问速度(简单的哈希表优化) 使用map数组的重要提醒 代码 提交结果 3.★P1160 队列安排 题目 分析 方法1:带头不循环双向链表的设计 方法2:带头循环的双向链表…...
【Mybatis】MyBatisPlus的saveBatch真的是批量插入吗?深度解析与性能优化
前言 在使用MyBatis-Plus进行批量数据插入时,许多开发者会发现:即使调用saveBatch方法,数据库仍会产生大量INSERT语句。本文将深入源码揭示背后的真相,并提供3种性能优化方案,让你的批量插入速度提升10倍!…...

内联函数(c++)
预处理:优点:内嵌到目标代码,减少函数的调用。 缺点:在预处理阶段完成替换,避免了语义上的差错。 egg: #define SQR(X) ((X)*(X)) 函数:优点:完成了某一类操作的抽象,…...

R7周:糖尿病预测模型优化探索
🍨 本文为🔗365天深度学习训练营中的学习记录博客 🍖 原作者:K同学啊 一、数据预处理 1.设置GPU import torch.nn.functional as F import torch.nn as nn import torch, torchvisiondevice torch.device("cuda"…...

线程怎么创建?Java 四种方式一网打尽
🚀 Java 中线程的 4 种创建方式详解 创建方式实现方式是否推荐场景说明1. 继承 Thread 类class MyThread extends Thread❌ 不推荐简单学习、单线程场景2. 实现 Runnable 接口class MyRunnable implements Runnable✅ 推荐更适合多线程共享资源3. 实现 Callable 接…...
前端如何连接tcp 服务,接收数据
在传统的浏览器前端环境中,由于浏览器的同源策略和安全限制,无法直接建立 TCP 连接。不过,可以通过 WebSocket 或者使用 WebRTC 来间接实现与 TCP 服务的通信,另外在 Node.js 环境中可以直接使用 net 模块建立 TCP 连接。下面分别…...

STM32之DHT11温湿度传感器---附代码
DHT11简介 DHT11的供电电压为 3-5.5V。 传感器上电后,要等待 1s 以越过不稳定状态在此期间无需发送任何指令。 电源引脚(VDD,GND)之间可增加一个100nF 的电容,用以去耦滤波。 DATA 用于微处理器与DHT11之间…...

工业相机——镜头篇【机器视觉,图像采集系统,成像原理,光学系统,成像光路,镜头光圈,镜头景深,远心镜头,分辨率,MTF曲线,焦距计算 ,子午弧矢】
文章目录 1 机器视觉,图像采集系统2 相机镜头,属于一种光学系统3 常规镜头 成像光路4 镜头光圈5 镜头的景深6 远心镜头 及 成像原理7 远心镜头种类 及 应用场景8 镜头分辨率10 镜头的对比度11 镜头的MTF曲线12 镜头的焦距 计算13 子午弧矢 图解 反差 工业…...
如何在Spring Boot中禁用Actuator端点安全性
在 Spring Boot 应用中,Spring Boot Actuator 提供了一系列用于监控和管理应用的端点(如 /actuator/health、/actuator/metrics),这些端点默认可能受到 Spring Security 的保护,要求身份验证或授权。然而,在…...
第48讲:空间大数据与智慧农业——时空大数据分析与农业物联网的融合实践
目录 🧠 一、什么是空间大数据? 📡 二、农业物联网:数据采集的神经末梢 🔁 三、融合应用:空间大数据 + 农业IoT = 决策大脑 1. 精准灌溉管理 2. 时空病虫害预警 3. 农业碳监测与生态评估 💡 四、技术实践案例:农田干旱预警系统 📌 场景设定: 🛠 数据…...

openwrt查询网关的命令
方法一:route -n 方法二:ip route show...

华为OD机试真题——查找接口成功率最优时间段(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
2025 A卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录…...
SiamMask原理详解:从SiamFC到SiamRPN++,再到多任务分支设计
SiamMask原理详解:从SiamFC到SiamRPN,再到多任务分支设计 一、引言二、SiamFC:目标跟踪的奠基者1. SiamFC的结构2. SiamFC的局限性 三、SiamRPN:引入Anchor机制的改进1. SiamRPN的创新2. SiamRPN的进一步优化 四、SiamMask&#x…...
Gradle安装与配置国内镜像源指南
一、Gradle简介与安装准备 Gradle是一款基于JVM的现代化构建工具,广泛应用于Java、Kotlin、Android等项目的构建自动化。相比传统的Maven和Ant,Gradle采用Groovy或Kotlin DSL作为构建脚本语言,具有配置灵活、性能优越等特点。 在开始安装前…...

【“星睿O6”AI PC开发套件评测】开箱+刷机+基础环境配置
开箱 很荣幸可以参与“星睿O6”AI PC开发套件评测,话不多说先看开箱美图,板子的包装还是蛮惊艳的。 基础开发环境配置 刷机 刷机参考这里的文档快速上手即可,笔者同时验证过使用USB和使用NVMe硬盘盒直接在硬盘上刷机,操作下来建…...

力扣面试150题--环形链表和两数相加
Day 32 题目描述 思路 采取快慢指针 /*** Definition for singly-linked list.* class ListNode {* int val;* ListNode next;* ListNode(int x) {* val x;* next null;* }* }*/ public class Solution {public boolean hasCycle(ListNod…...
Dapper的数据库操作备忘
Dapper是很好的C#生态的ORM工具 获取单条记录 var row conn.QueryFirstOrDefault("select abc as cc"); if (row null) return; string priField row.cc; //直接访问字段根据动态的字段名获取值,则需要先转为字典接口 var dict (IDictionary<string, objec…...

STM32 TIM输入捕获
一、输入捕获简介 IC(Input Capture)输入捕获输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数每个高级定时器和通用定…...

python项目实战-后端个人博客系统
本文分享一个基于 Flask 框架开发的个人博客系统后端项目,涵盖用户注册登录、文章发布、分类管理、评论功能等核心模块。适合初学者学习和中小型博客系统开发。 一、项目结构 blog │ app.py │ forms.py │ models.py │ ├───instance │ blog.d…...

白鲸开源与亚马逊云科技携手推动AI-Ready数据架构创新
在昨日举办的2025亚马逊云科技合作伙伴峰会圆桌论坛上,白鲸开源创始人兼CEO郭炜作为嘉宾,与亚马逊云科技及其他行业领袖共同探讨了“AI-Ready的数据架构:ISV如何构建面向生成式AI的强大数据基座”这一重要话题。此次论坛由亚马逊云科技大中华…...
【目标检测】目标检测综述 目标检测技巧
I. 目标检测中标注的关键作用 A. 目标检测数据标注的定义 目标检测是计算机视觉领域的一项基础且核心的任务,其目标是在图像或视频中准确识别并定位出预定义类别的目标实例 1。数据标注,在目标检测的语境下,指的是为原始视觉数据࿰…...
[AI技术(二)]JSONRPC协议MCPRAGAgent
Agent概述(一) AI技术基础(一) JSON-RPC 2.0 协议详解 JSON-RPC 2.0 是一种基于 JSON 的轻量级远程过程调用(RPC)协议,旨在简化跨语言、跨平台的远程通信。以下从协议特性、核心结构、错误处理、批量请求等角度进行详细解析: 一、协议概述 1. 设计原则 • 简单性:…...

探秘LLM推理模型:hidden states中藏着的self verification的“钥匙”
推理模型在数学和逻辑推理等任务中表现出色,但常出现过度推理的情况。本文研究发现,推理模型的隐藏状态编码了答案正确性信息,利用这一信息可提升推理效率。想知道具体如何实现吗?快来一起来了解吧! 论文标题 Reasoni…...

大数据开发环境的安装,配置(Hadoop)
1. 三台linux服务器的安装 1. 安装VMware VMware虚拟机软件是一个“虚拟PC”软件,它使你可以在一台机器上同时运行二个或更多Windows、DOS、LINUX系统。与“多启动”系统相比,VMWare采用了完全不同的概念。 我们可以通过VMware来安装我们的linux虚拟机…...
【GCC bug】libstdc++.so.6: version `GLIBCXX_3.4.29‘ not found
在 conda 环境安装 gcc/gxx 之后,运行开始遇到了以下的报错 File "/mnt/data/home/xxxx/miniforge3/envs/GAGAvatar/lib/python3.12/site-packages/google/protobuf/internal/wire_format.py", line 13, in <module>from google.protobuf import de…...
Android killPackageProcessesLSP 源码分析
该方法用于终止指定包名/用户ID/应用ID下符合条件的应用进程,涉及多进程管理、资源冻结、进程清理及优先级更新等操作。核心流程分为进程筛选、资源冻结、进程终止与资源恢复三个阶段。 /*** 从已排序的进程列表中,提取从指定起始索引 startIdx 开始的连…...

驱动开发硬核特训 · Day 16:字符设备驱动模型与实战注册流程
🎥 视频教程请关注 B 站:“嵌入式 Jerry” 一、为什么要学习字符设备驱动? 在 Linux 驱动开发中,字符设备(Character Device)驱动 是最基础也是最常见的一类驱动类型。很多设备(如 LED、按键、…...
CDN加速http请求
一、CDN加速定义 CDN(Content Delivery Network,内容分发网络)是通过全球分布式节点服务器缓存网站内容,使用户就近获取数据的技术。其核心目标是缩短用户与内容之间的物理距离,解决网络拥塞、带宽不足等问题ÿ…...
SpringCloud微服务架构设计与实践 - 面试实战
SpringCloud微服务架构设计与实践 - 面试实战 第一轮提问 面试官:马架构,请问在SpringCloud微服务架构中,如何实现服务注册与发现? 马架构:在SpringCloud中,Eureka是常用的服务注册与发现组件。服务提供…...
关于位运算的一些小记
目录 1.判断一个整数是不是2的幂 2.判断一个整数是不是3的幂 3.大于n的最小的2次幂的数 4.交换两个数 5.找到1-n中缺失的数字 6.判断数组中2个出现次数为奇数的数 6.求给定范围内所有数字&的结果 7. 求出现次数少于m的数 1.判断一个整数是不是2的幂 提取出二进制里最…...