【数据结构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();
			}
			else
				break;
		}
		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++中各种容器内元素的访问,但不同的容器有不同的迭代器,初学者可以将迭代器理解为指针

 迭代器使用方法:

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 学习记录

基本常识 row-size-limitsblob&#xff1a; BLOB and TEXT columns cannot have DEFAULT values.Instances of BLOB or TEXT columns in the result of a query that is processed using a temporary table causes the server to use a table on disk rather than in memory b…

C++11——新的类功能与可变参数模板

系列文章目录 文章目录 系列文章目录一、新的类功能默认成员函数类成员变量初始化强制生成默认函数的关键字default禁止生成默认函数的关键字delete继承和多态中的final与override关键字 二、可变参数模板递归函数方式展开参数包逗号表达式展开参数包STL容器中的empalce_back与…

写点东西《JWT 与会话身份验证》

写点东西《JWT 与会话身份验证》 身份验证与授权 JWT 与session身份验证 - 基本差异 什么是 JWT&#xff1f; JWT 结构&#xff1a; JWT 工作流程&#xff1a;优势: 安全问题&#xff1a; 处理令牌过期&#xff1a; 基于session的身份验证&#xff08;通常称为基于 cookie 的身…

工程对接大模型流式和非流式对话底层原理解析

文章目录 前言一、非流式输出设计二、stream流式输出设计三、手撸一个流式输出项目总结 前言 之前对接过OpenAi大模型的官方API&#xff0c;可以看到它有一个Stream参数&#xff0c;设置成true的时候就是流式的对话输出&#xff0c;现象就是一段一段的往外崩。 官方手册的地址…

蓝桥杯训练|基础语言Day1 - STL pair vector list stack queue set map容器

学习目标&#xff1a; 博主介绍: 27dCnc 专题 : 算法题入门 &#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d; ☆*: .&#xff61;. o(≧▽≦)o .&#xff61…

Python爬虫案例展示:实现花猫壁纸数据采集

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 环境使用: Python 3.10 Pycharm 模块使用: import requests >>> pip install requests win R 输入cmd 输入安装命令 pip install requests 安装即…

Springboot各种请求参数详解

文章目录 请求Postman**为什么需要Postman****什么是Postman****Postman使用教程** 请求参数简单参数实体参数数组参数集合参数![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/eba0ca80e3724412ae4c79af72b859c3.png#pic_center)日期参数json参数路径参数总结 请求…

STM32CubeMX教程31 USB_DEVICE - HID外设_模拟键盘或鼠标

目录 1、准备材料 2、实验目标 3、模拟鼠标实验流程 3.0、前提知识 3.1、CubeMX相关配置 3.1.0、工程基本配置 3.1.1、时钟树配置 3.1.2、外设参数配置 3.1.3、外设中断配置 3.2、生成代码 3.2.0、配置Project Manager页面 3.2.1、设初始化调用流程 3.2.2、外设中…

ESP8266 控制之 : 使用 RingBuffer USART1 和 USART3互传

简介 使用Buffer来避免数据的丢失, 或许你自己在使用串口进行收发时会丢失数据, 现在我们就来简单使用一下RingBuffer创建Rx、Tx的Buffer来避免发送接收丢包或数据丢失问题。 扩展知识 RingBuffer的介绍, 看完大概也就知道了&#xff0c;实在不知道就看看下面的代码 线路连接…

详解操作系统各章大题汇总(死锁资源分配+银行家+进程的PV操作+实时调度+逻辑地址->物理地址+页面置换算法+磁盘调度算法)

文章目录 第三章&#xff1a;死锁资源分配图例一例二 第三章&#xff1a;银行家算法第四章&#xff1a;进程的同步与互斥做题步骤PV操作的代码小心容易和读者写者混 1.交通问题&#xff08;类似读者写者&#xff09;分析代码 2.缓冲区问题&#xff08;第二个缓冲区是复制缓冲区…

实现元素进入界面的平滑效果

先看效果&#xff1a; 实现思路&#xff1a;获取页面中需要加载动画的节点&#xff0c;用元素的animate()方法创建一个动画对象&#xff0c;并传入两个关键帧&#xff0c;接着使用IntersectionObserverAPI创建观察对象&#xff0c;用于观察元素进入页面。当元素进入界面时&…

【数据分享】1929-2023年全球站点的逐年平均气温数据(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;其中又以气温指标最为常用&#xff01;说到气温数据&#xff0c;最详细的气温数据是具体到气象监测站点的气温数据&#xff01;本次我们为大家带来的就是具体到气象监…

CSS--Emmet 语法

Emmet语法的前身是Zen coding,它使用缩写,来提高html/css的编写速度, Vscode内部已经集成该语法. 目录 1. 快速生成HTML结构语法 1.1 快速生成HTML结构语法 2. 快速生成CSS样式语法 2.1 快速生成CSS样式语法 1. 快速生成HTML结构语法 1.1 快速生成HTML结构语法 1. 生成标…

2.【Vue3】Vue 基本使用——局部使用Vue

文章目录 1. 快速入门2. 常用指令2.1 v-for2.2 v-bind2.3 v-if 与 v-show2.4 v-on2.5 v-model 3. 生命周期4. Ajax 函数库 Axios4.1 Axios 基本使用4.2 Axios 请求方式别名 1. 快速入门 现在需要将 “hello vue3” 这样一个字符串渲染到页面上进行展示。 这个需求并不陌生&…

JVM系列——对象管理

JVM对象分布 对象头 第一类是用于存储对象自身的运行时数据&#xff0c;如哈希码&#xff08;HashCode&#xff09;、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等 另外一部分是类型指针&#xff0c;即对象指向它的类型元数据的指针&#xff0c;Java 虚…

【ArcGIS微课1000例】0096:dem三维块状表达(层次地形模型)

文章目录 一、DEM表达方式二、层次模型表达三、注意事项一、DEM表达方式 DEM数字高程模型的表达方式通常有以下4种: 1. 规则格网 2. 不规则三角网 3. 等高线 4. 层次地形模型 作为栅格地理数据,DEM 数据具有2.5维的特征,能够以三维表面的形式进行三维空间表达。但受其数…

Web 开发 6:Redis 缓存(Flask项目使用Redis并同时部署到Docker详细流程 附项目源码)

大家好&#xff01;欢迎来到第六篇 Web 开发教程&#xff0c;今天我们将探讨一个非常重要的话题&#xff1a;Redis 缓存。作为一个互联网开发者&#xff0c;你一定知道在处理大量请求时&#xff0c;性能优化是至关重要的。而 Redis 缓存正是帮助我们提升系统性能的利器。Redis …

爬虫基础-计算机网络协议

一个数据的传输 这些设备的数据转发是通过协议来完成的&#xff0c;整个互联网可以说是完全由网络协议来维持的 不同的协议分工不同&#xff0c;比如ip协议确保了ip寻址&#xff0c;tcp协议确保了数据完整性 IP地址和URL ip地址 整个网络传输可以比作快递&#xff0c;数据就…

2023年度总结——忙忙碌碌,终有归章

思来想去&#xff0c;还是决定写一篇年终总结&#xff0c;一来算是对23年的一年的回顾&#xff0c;二来是对24年的展望。记得22年也写过一篇年度总结&#xff0c;题目是《2022年度总结——一切都在慢慢变好》。今年&#xff0c;我想起的题目是《2023年度总结——忙忙碌碌&#…

在Temu跨境电商平台上,如何快速出单?

随着越来越多的商家选择入驻Temu跨境电商平台&#xff0c;一旦入驻申请通过&#xff0c;商家就可以开始上架商品并等待订单的产生。然而&#xff0c;很多新手跨境电商卖家都面临一个共同的问题&#xff0c;那就是&#xff1a;Temu出单快吗&#xff1f;Temu上架多久能出单&#…