自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(36)
  • 收藏
  • 关注

原创 题解 洛谷 Luogu P1828 [USACO3.2] 香甜的黄油 Sweet Butter 最短路 堆优化Dijkstra Floyd C++

思路:以每头奶牛所在的牧场为起点,求得到全图各个点的最短距离,再枚举全图所有点,计算从所有起点到某点的距离之和,取最小值即可。可以循环依次跑 Dijkstra,也可跑一遍 Floyd。后者更好写,但前者更快,实测前者时间效率约为后者的 6倍。细节:每个牧场可能有不止一头奶牛,最后结算的距离需要乘上每个牧场的奶牛的头数

2025-02-10 20:41:01 237

原创 题解 洛谷 Luogu P1983 [NOIP 2013 普及组] 车站分级 拓扑排序 C++

思路:大小等级划分中,要划分的级别的数目的最小值,就是 DAG 的层数,通过拓扑排序求得。建模:知道了这个题要用拓扑排序做后,最关键的就是:怎么建图?一个车次中,停靠的站台级别大小不确定,未停靠的站台的级别小于停靠的站台。所以在未停靠的站台与停靠的站台之间建边,令未停靠的站台指向停靠的站台。如何枚举未停靠的站台与停靠的站台?可以用标记数组记录某个站台是否发生停靠。我没这么做,我是用双指针的,不过二者效率差别不大,时间效率差不多,空间效率上,双指针只比这样节省了 bool[1000] 的空间

2025-02-09 14:52:12 462

原创 题解 洛谷 Luogu P1038 [NOIP 2003 提高组] 神经网络 拓扑排序 C++

为什么用拓扑排序?拓扑排序的主要应用之一就是基于 DAG (有向无环图) 的信息传递,这也是一种动态规划。本题的话,就是按拓扑序列传递 c[x] * w。具体地说,c[y] += c[x] * w (边的方向为 x >> y),累加之后减去阈值 u。题目要求分层,所以我们要逐层操作

2025-02-09 11:47:19 373

原创 题解 洛谷 Luogu P1955 [NOI2015] 程序自动分析 并查集 离散化 哈希表 C++

主要用到的知识是并查集 (如何实现并查集,这里不赘述了)。若 xi = xj,则合并它们所在的集合。若 xi != xj,则 i 和 j 若在同一个集合,则 false。但是用最简单的并查集并不能 AC 本题,因为 i、j 相当大,数组承受不了。需要做离散化。用哈希表做离散化比较方便。需要在处理完所有 = 情况时才能处理 != 情况,否则 != 会漏判后面再合并的情况。虽然每组测试数据是 n 行,但是每行可能有两个数据需要做离散化,所以 N 要开 2*5^10+

2025-02-01 03:00:53 387

原创 题解 信息学奥赛一本通/AcWing 1118 分成互质组 DFS C++

为什么要搜索,贪心不可以做吗?贪心还真不行,不妨试试:贪心思路:能入则入:如果一个数能放进已有的分组,就放进去,而不是新建分组。这样的贪心思路确实能过样例数据,但是不能过所有数据,如:n{ 4 }, arr{ 3,7,6,14 }。若 "能入则入",则 3 >> 分组1,7 >> 分组1,6 >> 分组2,14 >> 分组3,这样要分 3 组。但这不是最优解,最优解是分 2 组:{ 3,14 }, { 7,6 }。通过这个数据我们不难发现,一个数放入一个分组,会影响后续的数放入这个分组

2025-01-27 05:24:05 987

原创 题解 洛谷 Luogu P2853 [USACO06DEC] Cow Picnic S 搜索 C++

分别以每头奶牛所在的牧场为起点进行搜索,每轮搜索不重复搜,用计数变量统计每个牧场被搜到到的次数,次数 = 奶牛总数,就计入答案

2025-01-25 02:36:58 318

原创 题解 洛谷 Luogu P1113 杂务 图论 BFS C++

从工作之间的指向性关系不难看出这是基于有向图的问题。边从前置工作通向后置工作,表示完成了前置任务后才能完成后置工作。再模拟这个过程,可以发现这个过程非常像搜索,且更像 BFS,前置工作少的大致在更先搜到的层,前置工作多的大致在更后搜到的层。设 dist[i] 为从开始搜索一直到完成工作 i 所需的时间,t[i] 为完成工作 i 本身需要的时间,若 x 通向 y,则 dist[y] = dist[x] + t[y]。dist[i] 的最大值就是所求答案。但这和一般的 BFS 又不一样,以输入样例为例

2025-01-25 02:24:33 728

原创 题解 洛谷 Luogu P4715 【深基16.例1】淘汰赛 C++

2^7 也就 128 个数据,直接暴力模拟决出胜者的过程就行了。每轮操作,数组中的元数数量减半,仅保留特定下标组中能力值较大的那个。特定下标组,就是题目所说的某场比赛中参赛二国对应的下标。如剩 8 个参赛国时,有 (0, 1), (2, 3), (4, 5), (6, 7) 四个下标组,分别存入 0, 1, 2, 3。只剩两个参赛国时,输出能力值较小者的编号。因为能力值和编号绑定,我们存的时候把它们两个存一起,用 pair<int, int> 就行了。pair 对象之间默认的大小比较,first 的优先级高

2025-01-24 16:11:29 295

原创 题解 CodeForces 131D Subway BFS C++

思路:先找到图中的唯一环,然后从环出发进行 BFS,得到其他点到环的距离。共计两次 BFS,详情如下:怎么找环?不断从图中删掉出度为 1 的点,删到不能再删为止,剩下的一定都是环上的点。为什么这么做可以找到环?核心思路是删掉不在环上的点,保留在环上的点。画个符合题意的图分析一下,不难得出,环上的点出度不小于 2,出度为 1 的一定不是环上的点。直接删掉出度为 1 的点。随着出度为 1 的点被不断删除,原先出度不小于 2 的不在环上的点的出度也会减到 1,最终被删掉。环上的点不会在此过程中被删掉

2025-01-21 20:16:41 2122

原创 题解 CodeForces 1037D Valid BFS? 三种解法 C++

易错点解读:连续节点并非同层就行,还有一个重要的点是,子树顺序要与父节点顺序对应。如:1 2 3 [2 的子节点] [3 的子节点] 才行,1 2 3 [3 的子节点] [2 的子节点] 就不行。解法一:按输入顺序生成 BFS 序列,比较输入序列与生成序列。BFS 序列可能有很多,根本原因如题目所说 "选择每个顶点的邻居的顺序可以变化",即同层节点,入队的顺序有很多种。那我们可以按题目给出的序列重定义入队顺序,对于某节点的子节点,先在序列中出现,就先入队,比较生成的 BFS 序列与所给序列是否相同即可

2025-01-20 21:44:42 2142

原创 题解 CodeForces 268B Buttons C/C++

模拟,找规律通过确定第k次按哪个按钮之前需要几次前置操作,得出规律以共4 个按钮为例,假设正确顺序为4321确定第1 个按钮前:1 弹起,2 弹起,3弹起,确定为4,前置操作3*1次确定第2个按钮前:41 弹起,42弹起,确定为3,前置操作2*2 次确定第3个按钮前:431 弹起,确定为2,前置操作1*3 次按下全部:4321,4 次可以发现,为了确定第k 个按钮,每轮都需要带上k-1 个"累赘"按钮(因为按错了会导致这些按钮全都被弹起来)

2025-01-20 01:27:46 590

原创 题解 CodeForces 430B Balls Game 栈 C/C++

祖玛游戏/一维消消乐,找到一个消除点,并向两端扩展可以在脑中想象一下这个过程,这和括号序列匹配很像事件之间都是完全包含关系,不难想到,可以用栈解决此外,将相连的相同颜色的球视为一个整体 (一个括号)会使我们处理起来方便得多,因此我们先对输入的内容做一个预处理,将颜色相同的球合并结构体 A 的一个对象就是相连的相同颜色的球的一个整体color表示整体的颜色,num表示整体包含的球的数量将预处理结果存入 arr,然后遍历 arr,寻找可以消除的位置,之后进行 "括号序列匹配"

2025-01-15 22:19:39 1015

原创 题解 洛谷 Luogu P1135 奇怪的电梯 广度优先搜索 BFS C/C++

一道比较裸的 BFS,就是把走迷宫每次搜周围相邻四格,改成了楼层每次搜上下方向的某层而已。P1135 奇怪的电梯 - 洛谷 | 计算机科学教育新生态。感觉这个题难度只有普及-

2024-12-23 14:26:25 364

原创 题解 洛谷 Luogu P2895 [USACO08FEB] Meteor Shower S 广度优先搜索 BFS C++

根据题意,只有当 t[x][y] + 1 < g[X][Y] 时,才能走到这个格子上。+ 1 是走向这个格子花费的时间。接下来就是愉快的 BFS 了。若所处格子为 (x, y),到达该格子的时间为 t[x][y]试图走向的格子为 (X, Y),其最早被陨石砸中的时间为 g[X][Y]用一个数组对陨石落下的时间进行预处理,记录每个格子最早被陨石砸中的时间。如果同一个格子有多个陨石砸下来的话,我们显然只要记录最早砸下来时间。正确处理陨石落下的时间,是 AC 这道题的关键。

2024-12-23 10:48:02 284

原创 题解 洛谷 Luogu P1182 数列分段 Section II 二分答案 C/C++

需要将 arr[i] 加入新分出的一段中,sum = arr[i], cnt++。若 sum + arr[i] <= M,就继续累加。是就记录答案并试图找更小的阈值,将区间改为 [l, m - 1],否则改为 [m + 1, r]设置一个累加变量 sum,若 sum + arr[i] > M,表明该段不能再加入 arr[i]P1182 数列分段 Section II - 洛谷 | 计算机科学教育新生态。二分答案,每次以区间 [l, r] 中点 m 为每段和的阈值。如何求以 m 为每段和的阈值时的划分段数?

2024-11-27 21:15:39 369

原创 题解 洛谷 Luogu P3853 [TJOI2007] 路标设置 二分答案 C/C++

二分答案,每次询问区间[l, r] 中点 m 是否为合法距离是就记录答案并试图找更小的合法距离,将区间改为 [l, m - 1],否则改为 [m + 1, r]如何判断 m 是否为合法距离?(相邻路标距离 - 小于 1 的小数) / m 即为这两个路标之间应增设的路灯数减去小于 1 的小数是考虑到了边界情况如距离为 80,m 为 20,80 / 20 = 4,而我们只需要增设 3 个路标全路段应增设的路标数不大于 k 就是合法的

2024-11-27 19:40:36 508

原创 题解 洛谷 Luogu P1873 [COCI 2011/2012 #5] EKO / 砍树 二分答案 C/C++

很简单的二分答案每次找区间中点 m,判断以 m 为高度砍下的木头是否够 h 即可

2024-11-19 12:09:50 285

原创 题解 洛谷 Luogu P2440 木材加工 二分答案 C/C++

1.left 初始值应为 1 而非 0,否则有可能出现除以 0 的情况 (没错,我 RE 了 2 个点才想起来)为什么会剩 2 个点 WA 呢,因为有这样的数据:n = 3, k = 2, arr = { 1, 3, 3 }这种情况下 r 设定为 arr[i] 最小值就不对了。2.一开始我是把 r 设定为 arr[i] 最小值的,这样 AC 了 6/8 的测试点。每次找区间中点 m,判断每段长度为 m 时木头段总数是否 >= k 即可。P2440 木材加工 - 洛谷 | 计算机科学教育新生态。

2024-11-19 12:03:52 518

原创 题解 洛谷 Luogu P1308 [NOIP2011 普及组] 统计单词数 C++

getline()会清除使当次 getline()终止的换行,而 cin不会因此 cin以换行终止,之后还需要 getline() 的话,需要用 getchar()吞换行Linux 的一些相关环境中,tolower还有一个宏版本,洛谷 C++ 环境就是这样的在此情况下,要将 tolower当作函数调用时,需要用 "::"指明每次用 find() 找,找得到且判定为单词,cnt 就 ++单词判定及后续处理细节在代码注释里

2024-11-01 14:56:41 426

原创 题解 力扣 LeetCode 739 每日温度 C++

739. 每日温度 - 力扣(LeetCode)数据结构 单调栈-优快云博客。就是单调栈的思路,具体见代码。

2024-10-25 20:59:15 489

原创 题解 力扣 LeetCode 11 盛最多水的容器 贪心 双指针 对撞指针 C++

这种最优解题目,一般涉及到贪心。要找两条线,为提高效率,选择使用双指针而不是暴力v = min(h[l], h[r]) * (r - l)贪心策略:我们每次将 l或 r移动一步,思考如何使得 v尽可能地大无论是移动一步 l还是移动一步 r,(r - l)都是一样的关键在于 min()中的内容。假设 h[l]大 h[r]小,min()返回 h[r]此时若移动 l,h[l] 如果仍 >= h[r],那 min() 还是返回 h[r],v变小

2024-10-19 14:30:48 448

原创 题解 力扣 LeetCode 42 接雨水 双指针 滑动窗口 对撞指针 C++

这题暴力一下就能过的,还有双指针-对撞指针的优化版本,感兴趣的可以去搜一下这里介绍一种双指针-滑动窗口的写法思路:每轮操作找一个 "凹陷处",并统计。"凹陷处" 找法:先找凹陷处左侧最高点,若满足 i

2024-10-18 18:41:07 860

原创 题解 HZOJ 511 最少操作次数 贪心 正难则反 C/C++

需要贪心,不断贪当次最优解,以获得全局最优解。当次最优解又该怎么考虑呢?初步设想:k > 1时,a * k后 a 的变化量最大,应该多做 * k 的操作用题目验证:2 >> 4 >> 8 >> 9 >> 10,是 4步而不是 3步,出了什么问题?再次思考:正是因为 * k后 a 的变化量大,导致 a * k形成的数列相邻元素差值过大当 b处在该数列相邻元素中间时,最后一次 * k完需要很多次 + 1才能将 a修正到 b+ 1 起到一个修正的作用。先 + 1,再 * k

2024-10-13 09:15:13 478

原创 题解 洛谷 Luogu P1314 [NOIP2011 提高组] 聪明的质监员 二分算法 二分答案 前缀和 C/C++

目的:在 [wmin, wmax] 中查找使检验结果 y 与标准值 s 差的绝对值的最小值 |y - s|特征:1.在某区间内查找一个数 2.检验值 yi 随 W 的增长单调递减 3.需要频繁查询区间和值特征 1.2.对应二分答案,特征 3.对应前缀和思路:套二分答案模板,再通过前缀和实现一个 W & yi 的映射函数思路细节见代码注释

2024-10-12 21:39:00 578

原创 题解 HZOJ 284 超市卖货 C/C++

思路:每次寻找价格最高的商品,并尝试卖掉它:寻找未卖出商品的日期,优先锁定其保质期最后一天,若该日期已卖出则继续向前寻找能找到未卖出商品的日期时,收入增加,标记该日期代码实现:为了方便地找到价格最高的商品,我们先对商品价格连带其保质期进行排序因为我最近写了堆的底层结构,懒得用其他方法,所以就直接拿过来用了 (其实写个结构体然后 qsort() 一下就行,或者用 map就是注意在交换价格的同时还要交换保质期

2024-09-27 21:57:01 653

原创 题解 HZOJ 265 括号画家 C/C++

就是判断合法括号序列的升级版:找到最长合法括号序列括号序列合法性判断一般都会用到 栈 结构遇到左括号入栈,遇到右括号判断是否与栈顶括号匹配该题我们只需要在出入栈的过程中标记合法括号序列的位置:((({}[]((([]{()}}))[][]00011110001111110001111最后找到最长合法序列即可标记合法括号序列位置的方法:在括号匹配后完成如下操作:1.标记当前遍历位置,即合法左括号位置2.向前寻找并标记第一个未标记的位置,即合法右括号位置

2024-09-22 15:48:58 672

原创 纯C 生成二叉树广义表 根据广义表重构二叉树

讲解很多都写在注释里了,重构二叉树的过程后面单独拿出来讲重构二叉树:先定义函数功能:以根节点+括号对为单位进行处理根据 arr & p 还原二叉树,返回其根节点,并令 *p 指向队列中的合适位置(如碰到 '(' 就要在函数结束前再令 *p 后移一位,以跳出括号对)再写函数框架:以根节点为单位进行处理时,先看第一个节点,因为确保这个节点是根节点所以直接创建并初始化它的右边要么是 INT_MAX (结束),要么是 '(' (左右子树)再详细完善进入第一个括号对后应进行的操作

2024-09-16 08:55:23 700

原创 题解 力扣 LeetCode 105 从前序与中序遍历序列构造二叉树 C/C++

每次在中序遍历序列片段中找到前序遍历序列队首,这是该层的根节点该位置左侧是左子树,右侧是右子树再分别在左右子树序列中进行同样操作,找到左右子树的根节点,循环往复得到整棵树每次找到一层的根节点就从前序遍历序列中出队它前序遍历序列队列队首用head标记arrSize表示该次能访问的中序遍历序列片段的长度,若

2024-09-12 19:57:39 919

原创 题解 力扣 LeedCode 622 设计循环队列 C/C++

思路很简单但是实现起来比较繁琐,遇到问题可以参阅我的代码

2024-09-10 07:55:09 537

原创 题解 HZOJ 595 程序调用关系 C/C++

解决程序的运行、函数之间的运行一般都需要用到栈的思想栈直接用数组+top就能实现了我之前用C写过栈的底层了懒得再写一遍更简单的这种所以直接把之前写的搬过来了 (目标函数target是在最后给的所以不能边输入边处理,需要开个很大的二维数组s存储所有输入结果再处理处理结果存入栈S和a:每读到一个函数字符串就将其按顺序存入a,该函数字符串在a中的编号存入S每读到一个return就出栈一旦读到target就根据S中存入的编号输出a中对应的函数字符串

2024-09-08 12:36:42 756

原创 题解 力扣 LeetCode 19 删除链表的倒数第N个结点 C/C++

用指针数组记录链表各个节点的地址,遍历一遍就解决问题指针数组用 NULL 初始化遍历同时达成两个目的:1.获取链表大小 2.记录链表各节点地址遍历完令所删除节点的上一个节点指向所删除节点的下一个节点即可注意特判 n 为 count 的情况最近写过不止一道链表与数组结合的题通常单向不循环链表只能顺着->next一个一个访问过去但是与数组结合后可以赋予链表一部分顺序表的特点,通过下标就能访问了,这样会简单特别多

2024-09-02 07:22:35 408

原创 题解 力扣 LeetCode 61 旋转链表 C/C++

时间复杂度 O(N)1.特殊情况判断:head == NULL2.获取链表长度 length,该数据很有用,等下会用到好几次3.k %= length,防止 k过大出现多轮重复操作4.找到将来的末节点和头结点,记录将来的头结点后,将来的末节点->next = NULL举个例子:{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, NULL}rotate 3 >>{8, 9, 10, 1, 2, 3, 4, 5, 6, 7, NULL}7 是将来的末节点,8 是将来的头结点

2024-09-02 04:05:33 459

原创 题解 力扣 LeetCode 206 反转链表 C/C++ 三种思路

可以用迭代和递归来做,每种又可以具体写成不同样子,这里给出三种不同思路的代码先说迭代:遍历整个链表第一个节点是将来的最后一个节点,令它指向 NULL之后的每个节点指向之前的节点即可,每次反转前都要记录一下下一个节点否则会和之后的节点断开联系former 用来记录之前的节点latter 用来在该次反转前记录下一个节点p 不为 NULL 就继续执行,结束执行后返回 p循环体上半部分结束后判断 latter,因为我们要返回 p 作为最后一个节点的地址所以不能让 p == NULL

2024-09-01 08:03:44 2198

原创 题解 AtCoder ABC129 C Typical Stairs C/C++

不难看出此题是斐波那契数列的变种只需要在斐波那契数列的基础上讨论中断的情况1.当没有遇到坏阶梯时 2.遇到单独的坏阶梯时 3.遇到连续的坏阶梯时当没有遇到坏阶梯时:显然只需要简单地重复 a[i] = a[i - 1] + a[i - 2],最后输出ans(n)遇到单独的坏阶梯时,举个例子:前10个是好的,ans(10)=89,第11个坏了,跨2阶直接到第12个我们只有一种方式从第10个跨到第12个,显然ans(12)也是89我们在循环中写上判断

2024-08-27 19:50:31 418

原创 递归实现指数型、组合型、排列型枚举,按字典序输出

按位枚举即可,设枚举的位数是 i,该位最小可枚举的是 j,该位枚举到 n 为止我们需要一个数组来存放每位的数据。一开始我没开数组,结果写了半天hh所以我们需要设计的函数有 4 个参数,f(int i, int j, int n, int* pa)每位的数字,每次枚举完都需要输出,可以将此单独写成一个函数,print_ans(int i, int* pa)每次枚举完枚举下一位,递归,直到 n 结束

2024-08-19 18:52:19 330

原创 汉诺塔思路简述与代码实现 (输入圆盘数量输出操作次数版)

对于n个圆盘,进行一轮如下操作:0.视上面n-1个圆盘为一个整体1.将该整体移动到这样一个柱上:非最终目标柱 && 非该整体当前所在柱2.将最底下的那个圆盘移动到最终目标柱上3.将该整体移动到最终目标柱上对于以上的1.3.操作中的任何一个,如果该次操作的整体,圆盘数量不为1则直接先对该整体再进行一轮操作如果该次操作的整体,圆盘数量为1,则该次操作正常结束,不用再执行

2024-08-14 09:55:54 192 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除