简单算法题解报告

第五节 - 线性dp

A - Profits S

题目大意

奶牛们开始了新的生意,它们的主人约翰想知道它们到底能做得多好。这笔生意已经做了N(1≤N≤100,000)天,每天奶牛们都会记录下这一天的利润Pi(-1,000≤Pi≤1,000)。

约翰想要找到奶牛们在连续的时间期间所获得的最大的总利润。(注:连续时间的周期长度范围从第一天到第N天)。

大概思路

  • 首先定义一个dp数组用于表示以第i天结束的最大连续子序列的和
  • 初始化最大利润为第一天的利润
  • 然后比较第i天的利润和之前最大的利润和,将最大的储存在dp数组中,然后更新最大利润

B - 数字三角形

题目大意

要求在一个二维的数字金字塔(或称为三角形)中,从顶部出发,沿着每条路径只能向下或斜向下移动,找到一条路径,使得这条路径上经过的数字之和最大。

具体来说,输入的第一行是一个正整数r,表示数字金字塔的行数。接下来的r行,每行包含若干个整数,构成了数字金字塔的每一行。数字金字塔的顶部在第一行,只有一个数字,下一行有两个数字,以此类推,直到最后一行有r个数字。

程序需要输出从金字塔的顶部到底部任意处结束的路径,该路径上所有数字之和是最大的。输出仅包含一个整数,即可能得到的最大和。

大概思路

  • 定义一个二维数组,用于存储金字塔和动态规划的状态,将读取到的位置信息存入该数组
  • 从倒数第二行开始,逐行向上遍历,选择下方或者右下方的较大值,然后加上当前位置的值,状态转移
  • 输出顶部的值,及最大值

遇到的困难以及怎么解决的

一开始是想从上到下进行遍历,然后发现行不通,便转换思路,从下向上开始遍历

第二节 并查集

A - 并查集

题目大意

题目要求实现一个并查集数据结构,该数据结构支持两种操作:合并集合和查询元素是否属于同一集合。

输入数据包括两个整数N和M,分别表示元素的总数和操作的总数。接着是M行操作,每行包含三个整数Zi, Xi, Yi。

当Zi等于1时,表示执行合并操作,将元素Xi和元素Yi所在的集合合并为一个集合。

当Zi等于2时,表示执行查询操作,需要判断元素Xi和元素Yi是否属于同一个集合。如果属于同一个集合,则输出大写字母"Y";否则输出大写字母"N"。

输出格式要求对于每个查询操作(Zi=2),都输出一行结果,即"Y"或"N"。

大概思路

  1. 首先要创建三个函数,初始化并查集的,查找和合并
  2. 输入NM后,进行并查集的初始化
  3. 在输入ZXY后,进行合并,若两个元素的父节点不同,则进行合并
  4. 然后进行查询工作,查找元素所在的集合,看是否等于其父节点,不是,则进行路径压缩

B - 修复公路

题目大意

A地区在地震后,所有连接村庄的公路都受到了损坏。政府需要修复这些公路以恢复村庄间的交通。题目要求确定在所有公路修复完成后,任意两个村庄之间是否存在至少一条可通行的道路,并输出最早能实现这一目标的时间。

输入包括村庄的数量N和公路的数量M,以及每条公路连接的两个村庄和修复完成的时间。输出为最早的时间点,在该时间点之后任意两个村庄之间都存在至少一条修复完成的道路;如果无法达成这一条件,则输出-1。

大概思路

  1. 增加了边的权重
  2. 与上面主要不同的是,将边的权重进行排序后再进行并查集的查找和合并

遇到的困难以及怎么解决的

不太懂怎么进行边的比较与排序,然后经过网上搜索查找,找到一种边的比较函数

C - 亲戚

题目大意

如果两个人是亲戚,那么他们的亲戚也是彼此的亲戚。题目提供了n个人的信息,m个已确认的亲戚关系,以及p个询问的亲戚关系。

输入部分首先提供了三个整数n、m和p,分别表示总人数、已确认的亲戚关系数量和询问的亲戚关系数量。接下来的m行每行包含两个数,表示一对具有亲戚关系的人。然后,接下来的p行每行也包含两个数,表示需要询问的一对人是否具有亲戚关系。

输出部分需要针对每个询问输出"Yes"或"No",表示被询问的两个人是否具有亲戚关系。

大概思路

  • 将具有亲戚关系的元素进行合并
  • 最后进行查找工作,如果两个元素的父节点相同,则具有亲戚关系

D - 一中校运会之百米跑

题目大意

题目要求处理一个关于学生分组的问题。首先,提供了一组学生的名字和若干条将他们分组的信息。接着,需要回答一系列查询,判断特定的两个学生是否在同一组中。输入包括学生数量、分组信息数量和查询数量,以及具体的分组信息和查询。输出是对每个查询的回答,表明两个学生是否在同一组。

大概思路

思路和上面的题目差不多,都是进行并查集的查找和合并工作

遇到的困难以及怎么解决的

  • 前面的题目并查集的元素都是数字,这一题是字符串,自己对字符串的学习不够多,不懂怎么正确的进行读取与作用,后面经过上网查找,学习,能正确的读取与应用

第四节 数论基础

A - 快速幂

题目大意

给你三个整数 a, b, p,求a^b mod p

大概思路

  1. 首先,读取数据

  2. 初始化变量

  3. 对x进行模p操作,这是为了防止在计算过程中x的值变得过大。

  4. 使用一个while循环来进行模幂运算。循环的条件是y大于0。

  5. 在循环内部,首先检查y是否为奇数。如果是奇数,那么我们需要将当前的ans乘以x,并对p取模,以保证结果不会过大。然后,无论y是奇数还是偶数,我们都将y除以2,并将x平方后对p取模。当y变为0时,循环结束,此时的ans就是a的b次方模p的结果。

G - 线性筛函数

题目大意

给定一个范围 n ,有 q 个询问,每次输出第 k 小的素数。

输入,第一行包含两个正整数 n , q n,qn,q,分别表示查询的范围和查询的个数。
接下来 q qq 行每行一个正整数 k kk,表示查询第 k kk 小的素数。

大概思路

筛法的大概思路是:如果一个数是素数,则将所有k的倍数标记为非素数,然后将所有标记为素数的数存入prime数组,最后按照题目要求输出这个数组的元素

第一节 搜索、树

A - 迷宫

题目大意

给定一个由N行M列组成的迷宫,迷宫中有T个障碍物,起点和终点位置已知。迷宫中的移动只能沿着上、下、左、右四个方向,且每次只能移动一个方格。每个方格最多只能经过一次。

任务是计算从给定的起点到终点的所有可能路径数量,同时确保路径不会经过任何障碍物。

输入信息包括迷宫的大小(N和M)、起点和终点的坐标以及障碍物的坐标。输出是起点到终点的路径总数。

大概思路

  1. 首先,根据输入初始化一个 N×M 的迷宫,将障碍位置标记为不可通过。

  2. 然后,从起点开始进行深度优先搜索。每次搜索时,都尝试向上下左右四个方向移动。

  3. 如果移动后的位置在迷宫内,且没有被访问过,且不是障碍,则继续从这个位置进行深度优先搜索。

  4. 如果移动后的位置就是终点,那么就找到了一条从起点到终点的路径,方案数加一。

  5. 搜索完一个位置后,要将其标记为未访问,以便其他路径可以经过这个位置。

  6. 因为这道题数据范围较小,答案与路径有关,所以我们选用DFS

遇到的困难以及怎么解决的(若没有则无需写)

B - 马的遍历

题目大意

给定一个 n × m 的棋盘,棋盘上有一个马位于点 (x, y)。目标是计算马到达棋盘上每个其他点所需的最少步数。如果某个点无法到达,则输出 -1。

输入为四个整数:棋盘的行数 n、列数 m、马的起始位置 (x, y)。

输出为一个 n × m 的矩阵,每个元素表示马到达该点所需的最少步数,如果无法到达则为 -1。

大概思路

  1. 初始化一个 n×m 的矩阵,所有的值都设为 −1,表示马还没有访问过这个位置。

  2. 将马的初始位置设为 0,表示马已经在这个位置上。

  3. 创建一个队列,并将马的初始位置加入队列。

  4. 当队列不为空时,取出队列的第一个元素,然后遍历马可以移动的所有位置(一共有8个方向)。对于每一个可以移动的位置,如果马还没有访问过,并且没有超出棋盘的边界,那么就将这个位置加入队列,并更新这个位置的步数(当前步数+1)。

  5. 重复步骤4,直到队列为空。

遇到的困难以及怎么解决的

没有接触过队列的知识,不懂得队列的作用以及怎么使用,经过网上查询相关知识,基本了解

C - 填涂颜色

题目大意

给定一个由数字0和1组成的方阵,其中1构成了一个或多个闭合圈。要求将所有在闭合圈内的0替换为2。

一个0被认为是在闭合圈内,如果从这个0出发,只能上下左右移动,并且不能到达方阵的边界,同时只能经过其他的0。

闭合圈可以是任意形状,但保证圈内的0是连通的(即任意一个0都可以通过移动到达另一个0)。

目标是将所有属于闭合圈的0替换为2,而方阵中的其他0保持不变。

大概思路

  1. 首先定义了四个方向的移动。

  2. 然后定义了一个广度优先搜索的函数。这个函数会对所有的0进行搜索,如果一个0可以通过上下左右四个方向的移动到达边界,那么这个0就不在闭合圈内,我们将其标记为-1。

  3. 接着,遍历整个方阵,将所有未被访问过的0(即在闭合圈内的0)填充为2。

  4. 最后输出填充后的方阵。

遇到的困难以及怎么解决的

D - 棋盘问题

题目大意

给定一个n*n的棋盘,其中某些位置是可摆放棋子的(用’#‘表示),而某些位置不能摆放(用’.'表示)。

需要在棋盘上摆放k个棋子,且任意两个棋子不能在同一行或同一列。

求解所有可能的摆放方案的数量。

大概思路

  1. 首先读取棋盘形状,然后从第0行开始放置棋子
  2. 进行深度优先搜索,结束条件是放完k个旗子和处理完所有行
  3. 遍历当前每一列,当前列是否为棋盘位置且无其他棋子,进行标记,然后继续处理下一行,最后回溯

M - 猫猫和企鹅

题目大意

问题描述了一个由n个居住区构成的树状结构,其中每个居住区(除了1号)都住着一只小企鹅。猫猫从1号居住区出发,希望拜访距离它在d以内的小企鹅。

大概思路

  1. 首先读取信息并添加到图中,并引用函数用于添加边,从1号居民区开始进行dfs
  2. 在dfs函数中,需遍历节点的所有边,并查询另一个节点是否被访问,然后计算距离,若小于d,则答案数加一

第三节 拓扑排序

C - 拓扑排序/家谱树

题目大意

要求通过编程整理这种关系,并输出一个序列,使得每个人的后辈都在他们之后列出。

具体来说,输入包括家族的人数和每个人后代的编号。每个人的后代编号以0作为结束标志。输出需要是一个序列,满足每个人的后辈都在他们之后列出。如果存在多种不同的序列,题目要求输出任意一种即可。

大概思路

  1. 需要使用队列的相关知识,用到入队函数和出队函数
  2. 然后需要拓扑排序函数,对队列进行处理
  3. 还需要临界矩阵表示的图

第五节 - 线性dp

A - Profits S

题目大意

奶牛们开始了新的生意,它们的主人约翰想知道它们到底能做得多好。这笔生意已经做了N(1≤N≤100,000)天,每天奶牛们都会记录下这一天的利润Pi(-1,000≤Pi≤1,000)。

约翰想要找到奶牛们在连续的时间期间所获得的最大的总利润。(注:连续时间的周期长度范围从第一天到第N天)。

大概思路

  • 首先定义一个dp数组用于表示以第i天结束的最大连续子序列的和
  • 初始化最大利润为第一天的利润
  • 然后比较第i天的利润和之前最大的利润和,将最大的储存在dp数组中,然后更新最大利润

B - 数字三角形

题目大意

要求在一个二维的数字金字塔(或称为三角形)中,从顶部出发,沿着每条路径只能向下或斜向下移动,找到一条路径,使得这条路径上经过的数字之和最大。

具体来说,输入的第一行是一个正整数r,表示数字金字塔的行数。接下来的r行,每行包含若干个整数,构成了数字金字塔的每一行。数字金字塔的顶部在第一行,只有一个数字,下一行有两个数字,以此类推,直到最后一行有r个数字。

程序需要输出从金字塔的顶部到底部任意处结束的路径,该路径上所有数字之和是最大的。输出仅包含一个整数,即可能得到的最大和。

大概思路

  • 定义一个二维数组,用于存储金字塔和动态规划的状态,将读取到的位置信息存入该数组
  • 从倒数第二行开始,逐行向上遍历,选择下方或者右下方的较大值,然后加上当前位置的值,状态转移
  • 输出顶部的值,及最大值

遇到的困难以及怎么解决的

一开始是想从上到下进行遍历,然后发现行不通,便转换思路,从下向上开始遍历

  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值