【数据结构1-1】线性表

线性表是最简单、最基本的一种数据结构,线性表示多个具有相同类型数据“串在一起”,每个元素有前驱(前一个元素)和后继(后一个元素)。根据不同的特性,线性表也分为数组(vector)、栈(stack)、队列(queue)、链表(list)等等。根据这些特性和数据结构可以解决不同种类的问题。

 一、寄包柜(vector or map)

 1.1 使用vector

vector和数组相比,vector可以改变长度,清空的时间复杂度为O(1)。

vector常用操作如下: 


AC代码:

我们可以建立一个二维数组s[x][y]来记录第i个柜子的第j个格子中的物品。根据本题的数据范围,需要开一个大约40GB的int数组,而本题的空间限制这有125MB,显然会超空间,所以我们可以用一个vector来解决。

先设定一个可以满足大多数情况且不超内存的二维可变数组,如果实际情况所需内存超过所开范围可以使用resize函数重新为vector分配空间。

#include <bits/stdc++.h> //头文件
using namespace std;
inline int read() //快读
{int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;
}
inline void write(int x) //快出
{if(x<0){putchar('-');x=-x;}if(x>9)write(x/10);putchar(x%10+'0');
}
int main() //主函数
{ios::sync_with_stdio(false); //输入输出优化流int n,q,f,x,y,z; //定义n=read(); //输入寄包裹个数和询问次数q=read();vector<vector<int> > a(n+1); //定义一个可变数组,初始化,总共0-n号寄包柜while(q--){f=read(); //输入操作种类if(f==1) //存包操作{x=read(); //输入y=read();z=read();if(a[x].size()<y+1) a[x].resize(y+1); //如果这个寄包柜不够大,就扩大新的寄包柜,直到能装下为止a[x][y]=z; //存包}else{x=read(); //输入y=read();write(a[x][y]); //输出下标为x,y的元素puts(""); //换行}}return 0; //结束
}

使用可变长度数组vector的方法可以使得二维数组中每一行的长度不一样,从而在一定程度上减少空闲空间的产生,不过这种方法有一定局限性。 


1.2 使用map

显然使用vector并不是最优写法,因为只有少量数组空间会被利用,大量空间会被浪费,这里我们可以想到使用离散化的方式来对稀疏数据进行操作,即使用map。

map常用操作如下:

AC代码:

由于本题中有柜号和格子号二维信息,所以使用map容器嵌套pair类型变量即可,不需要开辟二维map。

使用count函数可以实现对map中键值的存在性查找。

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>using namespace std;map<pair<long, long>, long> bag;int main()
{int n, q;cin >> n >> q;for (int i = 1; i <= q; i++){int type = 0;cin >> type;if (type == 1){int x, y, k;cin >> x >> y >> k;bag[{x, y}] = k;}else if (type == 2){int x, y;cin >> x >> y;if (bag.count({ x,y }) != 0){cout << bag[{x, y}] << endl;}}}
}

二、队列安排(list)

list是一种实际运用比较少的数据类型,一般可以使用vector来代替,list的优势在于可以快速的插入和删除链上元素,劣势在于只能使用迭代器进行顺序查找。 

list使用方法: 

AC代码:

 本题将每个同学看作一个节点,使用链表将其连接在一起。但由于list查找速度缓慢,同时随机插入节点会导致list中节点的编号混乱,为了减少遍历list查找节点浪费的时间,我们可以使用一个数组来顺序保存每一个节点的迭代器。从而实现O(1)量级的快速查找。

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <list>using namespace std;
using Iter = list<int>::iterator;const int maxN = 1e5 + 5;
list<int> List;
Iter pos[maxN];
bool be[maxN] = { false };int main()
{int N, M;cin >> N;List.push_front(1);pos[1] = List.begin();for (int i = 2; i <= N; i++){int k, p;cin >> k >> p;if (p == 0){pos[i] = List.insert(pos[k], i);}else{pos[i] = List.insert(next(pos[k]), i);}}cin >> M;for (int i = 1; i <= M; i++){int tmp;	cin >> tmp;if (tmp <= N && !be[tmp]){List.erase(pos[tmp]);be[tmp] = true;}}for (auto x : List){cout << x << " ";}
}

 list中的迭代器为list<int>::iterator,使用数组pos按照1~n顺序保存每个节点所在list中的位置。同时由于删除节点会耗费一定的时间,我们可以使用一个辅助数组be来保存list中每个节点的存在性,be数组与list节点一一对应。


三、验证栈序列(stack) 

栈是唯一的只能从一个开口增删数据的数据结构,使用push函数向栈中压入数据,使用pop弹出数据,使用top函数查看栈顶数据。

需要注意的是如果栈为空,仍然使用top函数会异常中断,报错。

stack使用方法:

AC代码:

本题使用栈对序列进行模拟。将pushed中数据依次入栈,当栈顶数与poped序列中某数相同时,将栈顶数出栈。若操作结束后,栈中仍然有残留数据,说明poped序列无法实现。

#include <iostream>
#include <string>
#include <algorithm>
#include <stack>using namespace std;int pushed[100005];
int poped[100005];
stack<int> stk;
int main()
{int q;	cin >> q;for (int cnt = 1; cnt <= q; cnt++){int num;	cin >> num;for (int i = 1; i <= num; i++)cin >> pushed[i];for (int i = 1; i <= num; i++)cin >> poped[i];int index = 1;for (int i = 1; i <= num; i++){stk.push(pushed[i]);while (stk.top() == poped[index]){stk.pop();index++;if (stk.empty())break;}}if (stk.empty()) cout << "Yes" << endl;else cout << "No" << endl;while (!stk.empty())stk.pop();}
}

本题中存在的坑在于当栈为空时,使用top函数会报错,需先用empty函数确认栈不为空后,才能使用top函数查看栈顶。 


四、海港(queue) 

queue(队列)为两端开口,的管道容器,一侧为入口,一侧为出口,可以实现先进先出,后进后出,无法随机增删,此外还有deque(双端队列),管道两侧均可以增删数据。

queue使用方法:

 AC代码:

本题可以将node结构塞入queue队列当中,node结构中存储某个人的信息,包括下船时间和国籍,由于下船时间已经从下到大排序,所以每次淘汰下船时间超过24h的人时只需要从出口端删除信息即可。

#include <iostream>
#include <string>
#include <algorithm>
#include <queue>using namespace std;struct node
{int Time;int Nation;
};
queue<node> ship;
int national[100005] = { 0 };int main()
{int n;	cin >> n;int count = 0;for (int cnt = 1; cnt <= n; cnt++){int t, k;cin >> t >> k;while (!ship.empty()){if (t - ship.front().Time >= 86400){national[ship.front().Nation] -= 1;if (national[ship.front().Nation] == 0){count -= 1;}ship.pop();}elsebreak;}for (int i = 1; i <= k; i++){int people; cin >> people;node tmp;tmp.Time = t, tmp.Nation = people;ship.push(tmp);if (national[tmp.Nation] == 0)count += 1;national[tmp.Nation] += 1;}printf("%d\n", count);}}

代码逻辑为:

  1. 先淘汰下船时间超过24h的人,用一个national数组存储每个国籍的人数,若淘汰后某个国籍人数为0,那么count减1;
  2. 然后对当前时间下船的人操作,若该人的到来使得某个国籍的人数从0变为1,那么count加1.

五、营业额统计(set)

set能有序地维护同一类型的元素,但相同的元素只能出现一次。

也就是说,我们将数据插入set中后,set会自动帮我们排序(相当于优先队列)。

set使用方法:

AC代码: 

每次输入一个新的数x后,通过lowerbound操作找到set中大于等于x的第一个数。

  • 如果这是第一个数,直接插入到set里。
  • 这个数等于x,显然最小波动值为0,我们也不需要再插入一个x放到set里了。
  • 这个数大于x,通过set的特性可以很轻松的找到这个数的前驱,也就是小于x的第一个数。将两个数分别减去x,对绝对值取个min就好了。此时要将x插入到set中。
#include <iostream>
#include <string>
#include <algorithm>
#include <set>using namespace std;set<int> s;
set<int>::iterator r,l;
int main()
{int n;	cin >> n;int a;	cin >> a;s.insert(a);int ans = a;for (int i = 2; i <= n; i++){int tmp;		cin >> tmp;r = s.lower_bound(tmp);if (r == s.end()){ans += abs(tmp - *(--r));//k的前一个数,也就是小于tmp的最大数s.insert(tmp);continue;}else if (r == s.begin()){ans += abs(tmp - *r);s.insert(tmp);continue;}else{l = --s.lower_bound(tmp);ans += min(abs(tmp - *r), abs(tmp - *l));s.insert(tmp);}}cout << ans;
}

迭代器是一种检查容器内元素并遍历元素的数据类型,通常用于对C++中各种容器内元素的访问,但不同的容器有不同的迭代器,初学者可以将迭代器理解为指针

 迭代器使用方法:

  • 比较两个迭代器是否相等(==、!=)。
  • 前置和后置递增运算(++、--)(无法随机访问!)。
  • 读取元素的解引用运算符(*)。只能读元素,也就是解引用只能出现在赋值运算符的右边。
  • 箭头运算符(->),解引用迭代器,并提取对象的成员。

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

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

相关文章

代码随想录算法训练营DAY6 | 哈希表(1)

DAY5休息一天&#xff0c;今天重启~ 哈希表理论基础&#xff1a;代码随想录 Java hash实现 &#xff1a;java 哈希表-CSDN博客 一、LeetCode 242 有效的字母异位词 题目链接&#xff1a;242.有效的字母异位词 思路&#xff1a;设置字典 class Solution {public boolean isAnag…

shell脚本5 函数 数组

函数 试题1 查看版本 如果想更方便&#xff0c;可以建立一个专门存函数的文件 将func.sh里面的命令都移到func文件夹里面&#xff0c;在脚本里面执行文件夹更方便 输入echo $?反馈的结果都是0&#xff0c;都认为是正确的 无法使用$?去检验是否正确&#xff0c;所以要在后面增…

【Java反序列化】Shiro-550漏洞分析笔记

目录 前言 一、漏洞原理 二、Shiro环境搭建 三、Shiro-550漏洞分析 解密分析 加密分析 四、URLDNS 链 前言 shiro-550反序列化漏洞大约在2016年就被披露了&#xff0c;在上学时期也分析过&#xff0c;最近在学CC链时有用到这个漏洞&#xff0c;重新分析下并做个笔记&…

LocalContainerEntityManagerFactoryBean源码

是 Spring Data JPA 中的一个类&#xff0c;它用于创建 EntityManagerFactory 的实例&#xff0c;获取EntityManager实例 public class LocalContainerEntityManagerFactoryBean extends AbstractEntityManagerFactoryBeanimplements ResourceLoaderAware, LoadTimeWeaverAwar…

Java 集合 04 综合练习-查找用户是否存在

练习、 代码&#xff1a; public class User{private String id;private String username;private int password;public User() {}public User(String id, String username, int password) {this.id id;this.username username;this.password password;}public String getI…

Linux提权:Docker组挂载 Rsync未授权 Sudo-CVE Polkit-CVE

目录 Rsync未授权访问 docker组挂载 Sudo-CVE漏洞 Polkit-CVE漏洞 这里的提权手法是需要有一个普通用户的权限&#xff0c;一般情况下取得的webshell权限可能不够 Rsync未授权访问 Rsync是linux下一款数据备份工具&#xff0c;默认开启873端口 https://vulhub.org/#/envir…

go-zero 统一返回

1、整体目录结构 2、全局处理主入口 package manageimport ("net/http""github.com/zeromicro/go-zero/rest/httpx" )type Body struct {Code int json:"code"Message string json:"message"Result interface{} jso…

RocketMq源码搭建报错No route info of this topic: TopicTest

原因 因为broker没有注册到namsesrv中&#xff0c;导致无法创建Topic 解决办法 启动Borker时&#xff0c;指定namsesrv地址 over!!!

防御保护常用知识

防火墙的主要职责在于&#xff1a;控制和防护 --- 安全策略 --- 防火墙可以根据安全策略来抓取流量之 后做出对应的动作 防火墙分类主要有四类&#xff1a; 防火墙吞吐量 --- 防火墙同一时间能处理的数据量多少 防火墙的发展主要经过以下阶段&#xff1b; 传统防火墙&#xf…

SpringBoot之JWT登录

JWT JSON Web Token&#xff08;JSON Web令牌&#xff09; 是一个开放标准(rfc7519)&#xff0c;它定义了一种紧凑的、自包含的方式&#xff0c;用于在各方之间以JSON对象安全地传输信息。此信息可以验证和信任&#xff0c;因为它是数字签名的。jwt可以使用秘密〈使用HNAC算法…

Element table组件内容\n换行

漂亮的页面总是让人心旷神怡&#xff0c;层次清晰的页面让用户操作起来也是易于上手及展示。 如下的页面展示就是非常low的&#xff1a;用户根本阅读其中的数据。 在这个页面&#xff0c;根据用户填写过程生成多次填写记录&#xff0c;如果不进行层次性的展示&#xff0c;数据…

qemu调试kernel启动(从第一行汇编开始)

一、背景 大部分qemu调试kernel 都是讲解从start_kernel开始设置断点&#xff0c;然后开启调试&#xff1b; 但是我们熟悉linux启动流程的伙伴肯定知道&#xff0c;在start_kernel之前还有一段汇编&#xff0c;包括初始化页表及mmu等操作&#xff0c; 这部分如何调试呢&#x…

漏洞原理linux操作系统的SqlMap工具的使用

漏洞原理linux操作系统的SqlMap工具的使用 Linux操作系统基础操作链接: 1024一篇通俗易懂的liunx命令操作总结(第十课)-CSDN博客 kali的IP地址:192.168.56.1 实操 # kali中使用sqlmap http://192.168.56.1/ sqlmap -u http://192.168.56.1/news/show.php?id46 sqlmap -u …

​ArcGIS Pro 如何批量删除字段

在某些时候&#xff0c;我们得到的图层属性表内可能会有很多不需要的字段&#xff0c;如果挨个去删除会十分的麻烦&#xff0c;对于这种情况&#xff0c;我们可以使用工具箱内的字段删除工具批量删除&#xff0c;这里为大家介绍一下使用方法&#xff0c;希望能对你有所帮助。 …

如何创建用户友好的软件产品说明书?(上:建议篇)

之前我有写过关于制作和编写用户友好的产品说明书需要注意哪些地方&#xff0c;以及有哪些方法可以比较快速制作编写产品说明书。但是有网友在后台私信我&#xff0c;说想要知道细化到软件的产品说明书需要注意什么&#xff1f;所以我打算将关于“软件产品说明书”的主题分成两…

IDEA常用插件(本人常用,不全)

文章目录 一、图标提示类插件1、Lombok插件&#xff08;用户配合lombok依赖的工具&#xff09;2、MybatisX插件3、GitToolBox4、VUE.js&#xff08;vue编程使用&#xff09;5、ESLint&#xff08;vue编程使用&#xff09; 二、代码自动生成插件1、EasyCode插件&#xff1a;自动…

Android中下载 HAXM 报错 Intel® HAXM installation failed,如何解决?

最近在搭建 Flutter 环境&#xff0c;但是在 Android Studio 中安装 Virtual Device 时&#xff0c;出现了一个 问题 Intel HAXM installation failed. To install Intel HAXM follow the instructions found at: https://github.com/intel/haxm/wiki/Installation-Instructio…

爬虫学习笔记-xpath的基本使用

html示例 基本使用 #导入包 #pip install lxmlfrom lxml import etree# xpath解析 # 1.本地文件 etree.parse # 2.服务器响应的数据 etree.HTML()tree etree.parse(baidu.html) # 获取所有的ul下的li标签 l1 tree.xpath(//ul/li) print(l1) print(len(l1))# 获取所有带有id的…

某大厂关于Linux系统相关面试题

一、Linux系统和Shell 1、写一个sed命令&#xff0c;修改/tmp/input.txt文件的内容&#xff0c;要求&#xff1a;(1) 删除所有空行&#xff1b;(2) 在非空行前面加一个"AAA"&#xff0c;在行尾加一个"BBB"&#xff0c;即将内容为11111的一行改为&#xff1…

安防监控项目

一、安防监控项目的概述 安防监控项目是指利用先进的技术手段对特定区域、场所或对象进行全天候、全方位的监控和管理&#xff0c;以确保安全和防范各类安全风险。随着科技的不断发展&#xff0c;安防监控项目已经从传统的简单监控摄像头向数字化、智能化方向发展。这些项目广…