合集-C++题解
摘要:P1028 [NOIP 2001 普及组] 数的计算 题目描述 给出正整数 \(n\),要求按如下方式构造数列: 只有一个数 \(n\) 的数列是一个合法的数列。 在一个合法的数列的末尾加入一个正整数,但是这个正整数不能超过该数列最后一项的一半,可以得到一个新的合法数列。 请你求出,一共有多少个合法
阅读全文
摘要:Function 题目描述 对于一个递归函数 \(w(a,b,c)\) 如果 \(a \le 0\) 或 \(b \le 0\) 或 \(c \le 0\) 就返回值 \(1\)。 如果 \(a>20\) 或 \(b>20\) 或 \(c>20\) 就返回 \(w(20,20,20)\) 如果 \(
阅读全文
摘要:木材加工 题目描述 木材厂有 \(n\) 根原木,现在想把这些木头切割成 \(k\) 段长度均为 \(l\) 的小段木头(木头有可能有剩余)。 当然,我们希望得到的小段木头越长越好,请求出 \(l\) 的最大值。 木头长度的单位是 \(\text{cm}\),原木的长度都是正整数,我们要求切割得到的
阅读全文
摘要:[NOIP 2015 提高组] 跳石头 题目描述 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 \(N\) 块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步
阅读全文
摘要:洛谷P1314 [NOIP 2011 提高组] 聪明的质监员 题解 题目 题目传送门。 题解 思路 这题可以使用前缀和优化+二分答案法求解。 首先读入\(m\)组区间,左右端点分别存放到数组\(left_i\)和\(right_i\)中。二分查找\(W\),左边界\(l\)和右边界\(r\)初始值分
阅读全文
摘要:P1083 [NOIP 2012 提高组] 借教室 题解 题目 题目传送门。 题解 思路 这一题可以使用差分优化+二分答案法做。 二分查找一个值\(x\),代表前\(x\)个订单是否满足条件,每次在循环中调用一个函数\(check(int\ x)\),用于检测前\(x\)个订单是否可以满足。 \(c
阅读全文
摘要:P1902 刺杀大使 题解 题目 题目传送门。 题解 思路 这一题我们可以使用二分答案+BFS的解法。 我们二分整个部队受到的伤害最小值\(x\),每次使用\(check(int\ x)\)函数用于检验是否可以在最小值为\(x\)的情况下到达第\(n\)行。 随后就是BFS的板子了,从(1,1)开始
阅读全文
摘要:洛谷P1873 [COCI 2011/2012 #5] EKO / 砍树 题解 题目传送门。 思路 我们可以使用二分答案法。 二分查找砍树的高度\(H\),每次使用\(check(long\ long\ x)\)函数用于检测在\(x\)米高度时是否可以砍到\(m\)米以上的木头。 \(check\)
阅读全文
摘要:P2280 [HNOI2003] 激光炸弹 题解 题目 题目传送门。 题解 思路 这题是一道标准的二维前缀和模板题。 用\(s_{i,j}\)表示数组\(a\)从\(a_{1,1}\)到\(a_{i,j}\)的矩形内所有数值的和。我们在读入\(x,y,v\)后存起来,随后处理数据到前缀和数组内。 然
阅读全文
摘要:P8218 【深进1.例1】求区间和 题解 题目 题目传送门。 题解 思路 这题是一道一维前缀和模板题,使用数组\(s\)作为前缀和数组,\(s_i\)表示数值数组\(a\)中\(a_1\)到\(a_i\)的所有数值的和。求数组\(a\)中第\(l\)项到第\(r\)项的区间和就可以用\(s_r-s
阅读全文
摘要:P1719 最大加权矩形 题解 题目 题目传送门。 题解 思路 这题是一道二维前缀和的经典题目(可以说是模板题了)。 使用数组\(s\)表示数组\(a\)的二维前缀和,\(s_{i,j}\)表示\(a_{1,1}\)到\(a_{i,j}\)的和。需要求\(a_{i,j}\)到\(a_{k,l}\)的
阅读全文
摘要:P2367 语文成绩 题解 题目 题目传送门。 题解 思路 这题是一道经典的差分题。 使用一个数组\(c\)表示\(a\)的差分数组,\(c_i=a_i-a_{i-1}\)。当要修改第\(x\)到\(y\)同学的成绩时,只需要在\(c\)中的\(c_{x}+z\)和\(c_{y+1}-z\)就可以了
阅读全文
摘要:P1387 最大正方形 题解 题目 题目传送门。 题解 思路 这题可以使用二维前缀和解。(不懂什么是二维前缀和或者不会基本公式的可以先去网上搜一下,这篇文章不会讲基础的哦) 使用\(s\)存\(a\)的二维前缀和,枚举正方形的左上端点,再在内部枚举一个\(p\)代表正方形长度,从\(mxl\)(即当
阅读全文
摘要:P1014[NOIP 1999 普及组] Cantor 表 题解 题目 题目传送门。 题解 思路 这是一道有意思的经典递推题目。 通过肉眼观察和枚举样例理解,不难发现,第\(x\)条“/”斜线上有\(x\)项元素,当\(x\mod2=0\)时,第\(i\)项\(a_i\)/\(b_i\)中的分子\(
阅读全文
摘要:洛谷P1563 [NOIP 2016 提高组] 玩具谜题 题解 题目传送门。 思路 这题就是一道简单的小模拟题,唯一需要注意的是序号-1为顺时针数,+1为逆时针数。 代码 #include <bits/stdc++.h> #define endl '\n' using namespace std;
阅读全文
摘要:洛谷P4924 [1007] 魔法少女小Scarlet 题解 题目传送门。 思路 通过模拟几次顺时针和逆时针的转换,不难发现每次顺时针旋转后,第\(i\)行的内容往往就与原来的第\(i\)列内容有关,如下表: 1 2 3 4 5 6 7 8 9 顺时针旋转后: 7 4 1 8 5 2 9 6 3 同
阅读全文
摘要:洛谷P1518 [USACO2.4] 两只塔姆沃斯牛 The Tamworth Two 题解 题目传送门。 思路 使用简单的模拟思想来模拟Farmer John和2头牛的移动过程,唯一的难点在于如何判断是否永远无法抓到2头牛。 这个难点可以使用一个简单的六维bool型数组来判断,若在某一时间点,2个
阅读全文
摘要:洛谷P1786 帮贡排序 题解 题目传送门。 思路 使用结构体定义类型 person 表示一个人,结构体内成员变量需包含名字、职位、帮贡、等级、输入顺序(即ID),用 2 次 sort 排序将 person 数组排序。 第一次排序:cmp1 cmp1 是第一次排序时的自定义比较函数(用法如:sort
阅读全文
摘要:洛谷P1990 覆盖墙壁 题解 题目传送门。 本题是一道非常好的递推题,请认真阅读,争取不看代码自己写出答案。 思路 我们可以设 \(f_i\) 为覆盖 \(2\times i\) 的所有覆盖方案。显然,边界条件 \(f_0\)(即没有列了,不用覆盖)和 \(f_1\)(只有 1 列,即一个 \(\
阅读全文
摘要:洛谷P1010 [NOIP 1998 普及组] 幂次方 题解 题目传送门。 思路 使用一个函数 \(dfs\) 作为递归函数,传入一个参数 \(n\) 表示要分解 2 次幂的数。如果 \(n=1\),直接输出 \(2(0)\);如果 \(n=2\),输出 \(2\)。随后输出 \(2\),使用一个变
阅读全文
摘要:题目传送门。 思路 可以使用递归来解此题。 我们发现,当我们把第 \(n\) 和 \(n+1\) 个棋子移动到第 \(2\times n+1\) 和 \(2\times n+2\) 的空位上,再把第 \(2\times n-1\) 和 \(2\times n\) 个棋子移动到第 \(n\) 和 \(
阅读全文
摘要:本题做法 贪心策略+二分答案。 思路 贪心策略:让越往前的同学抄的书尽可能少,后面的尽可能多。 使用二分答案法,详细讲解\(check\)函数的写法。 \(check\)函数 传入一个参数\(x\),代表当前二分出的预定最短复制时间。从第\(m\)本书到第1本书反向遍历,若当前同学再抄第\(i\)本
阅读全文
摘要:本题做法 二分答案+BFS。 思路 对于输入的数据,使用4个数组\(head,tail,value,next\)记录每个点的第一条边、每条边的结尾、每条边的拥挤值以及每条边的下一条边。 随后使用二分答案法二分所求的答案,使用\(check\)函数检测是否可行。 \(check\)函数:从\(s\)点
阅读全文
摘要:本题做法 01分数规划+二分答案。 思路 二分答案\(x\),\(check\)函数内部将每个调料的\(v_i-xc_i\)求出,再从大到小排序,将前\(m\)个的值累加,返回这个和是否大于等于0。 代码 #include <bits/stdc++.h> #define endl '\n' #def
阅读全文
摘要:本题做法 二分答案+并查集。 思路 二分答案\(x\),使用并查集判断在\(x\)时刻内是否能够形成连通块。 若任意2点的曼哈顿距离(即\(x\)坐标和\(y\)坐标的差值之和)小于等于\(2x\)(因为2个点是同时在扩散的),则这2点在\(x\)时刻内是可以形成连通块的。将2点在并查集内连边在一起
阅读全文
摘要:本题做法 二分答案+贪心。 思路 二分一个答案\(x\),每次检测\(x\)是否可行。 遍历每一件衣服,先将原本的湿度值减去\(x\cdot a\),再判断,若已经干了(即湿度值\(\le0\)),则不再处理,否则使用烘干机烘干,记录使用的时间。最后若总时间小于等于\(x\),返回true;否则返回
阅读全文
摘要:本题做法 BFS。 思路 本题其实难就难在传送门如何存储。我的做法是使用 3 个 map 存储传送门,一个 map 叫做 \(exist\)(map<char,bool>),代表传送门 \(c\) 是否存在(就是有没有输入过了),是为了后面的存储判断做准备;第二个 map 叫做 \(lastdoor
阅读全文
摘要:本题做法 贪心+排序+双指针 two-pointers。 思路 对于这道题,我们不难发现,当每次跳跃的 \(|h_i-h_j|\) 越大,最后消耗的体力值就越多。 我们可以使用双指针,一个指向开头(即 \(l=1\)),另一个指向结尾(即 \(r=n\))。进行循环 \(i:1\sim n\) 次,
阅读全文
摘要:本题做法 BFS。 思路 简单的 BFS 打卡题。从 m 的位置开始 BFS,直到找到 d 的位置,此时由于是按照层序搜索的,所以步数一定是最少的,故直接输出步数,程序退出。最后如果 BFS 结束后依然没有输出,则直接输出 No Way!。 代码 #include <bits/stdc++.h> #
阅读全文
摘要:本题做法 二分查找,排序。 思路 我们可以先将科技创新奖的名单读入到 \(b\) 数组中,特殊贡献奖的名单读入到 \(a\) 数组中,然后先排序 \(a\) 数组,接着就开始遍历 \(b\) 数组,对于每一次遍历,我们在 \(a\) 中二分查找 \(b_i\),若存在,则输出 \(b_i\)。 为什
阅读全文
摘要:本题做法 位运算。 思路 这题的数据范围使用 int 存储不下,得用 unsigned int。 读入后,我们就要开始考虑如何获取高低位的问题了。 我们都知道,C++ 中的右移运算是可以将一个正整数的二进制右移一位的,我们要忽略后 16 位,我们就可以通过 n>>16 获取高位。 那怎么获取低位呢?
阅读全文
摘要:本题做法 Floyd 弗洛伊德最短路算法。 思路 求全源最短路,再输出 \(g[1]][n]\) 即可。 代码 #include<bits/stdc++.h> using namespace std; const int INF=0x7fffffff; const double EPS=1e-8;
阅读全文
摘要:本题做法 Dijkstra最短路+离散化思想。 思路 这其实是一道 Dijkstra 最短路的裸题,只需要对于每一次询问做一次 Dijkstra 然后判断输出即可。 这题有意思的点在于它的编号不是数字而是字符串,我们在这种情况下可以使用离散化思想,将每一个字符串通过 map 映射到一个唯一的数字上,
阅读全文
摘要:题外话 本题属于赛后补题系列,以后我会陆陆续续在这个系列中更新曾经比赛中未做出来的题。 本题做法 排序,贪心,差分。 思路 这题中每一个点的覆盖方式可以看做 2 种情况: 士兵一开始就部署在这个点上,不影响体力消耗。 士兵从相邻的 2 个点之一巡逻而来,体力消耗为 2 个点距离这个点的距离。 我们要
阅读全文
摘要:本题做法 前缀和思想、模拟和贪心。 思路 定义一个数组 \(pre[i]\) 表示油价数组 \(a\) 中 \(a[1]\sim a[i]\) 中的最小油价,递推公式为 \(pre[i]=\min\{pre[i-1], a[i]\}(i>1),pre[1]=a[1]\)。遍历距离数组 \(v\) 的
阅读全文
摘要:本题做法 数学。 思路 记 \(n=pq\) 为式 1,\(ed=(p-1)(q-1)+1\) 为式 2。 将式 2 展开,得到 \(ed=pq-p-q+2\),移项得到 \(p+q=pq-ed+2=n-ed+2\),正好是数据范围中定义的 \(m\)。 这样,我们就得到了 2 个式子: \[pq=
阅读全文
摘要:本题做法 数学。 思路 这题需要把上下界 \(L\) 和 \(R\) 分成 2 种情况讨论。 情况 1:\(R-L<n\) 当这种情况时,代表 \(L\) 和 \(R\) 并没有完全覆盖 1 个以上的 2 个相邻 \(n\) 的倍数之间的区间,当发生这种情况时,又要分成 2 种情况来讨论。 情况 1
阅读全文
摘要:本题做法 DFS。 思路 在主函数中枚举开始挖的地窖,然后在 DFS 途中不断更新答案及路径,最后输出即可。 代码 #include<bits/stdc++.h> using namespace std; const int INF=0x3f3f3f3f; const double EPS=1e-8
阅读全文
摘要:本题做法 拓扑排序。 思路 本题可以利用拓扑排序,每次找到入度为 0 的生物,然后将吃它的生物的路径计数加上它本身的计数,直到所有生物都被遍历到为止。最后输出答案即可。 代码 #include<bits/stdc++.h> typedef long long ll; typedef unsigned
阅读全文
摘要:本题做法 队列(queue)和结构体。 思路 我们一开始最容易想到的方法就是使用一个动态数组 vector 来存储数据,但是这样操作光是一次操作 1 的 \(c\) 达到极限数据 \(10^9\) 就会直接超时,时间复杂度为 \(O(c)\)。我们需要想一些优化思路。 定义结构体类型 node 代表
阅读全文
摘要:本题做法 数学。 思路 本题中,不难发现,一个数的各个数位之和(直到只有个位数),等于它模上 9(但是若它本身就是 9 的倍数,那么就是 9),即:记 \(S(n)\) 为各个数位之和(直到个位数),那么: \[S(n)=\begin{cases}n\bmod 9&\text{if } n\bmod
阅读全文
摘要:本题做法 动态规划 DP。 思路 本题其实就是在求前序的最长递增子序列长度和后序的最长递增子序列长度在某个点 \(i\) 之和的最大值。由于本题的数据范围为 \(1\le n\le 100\),直接用 \(O(n^2)\) 的 DP 求最长递增子序列就行了。 代码 #include<bits/std
阅读全文
摘要:本题做法 二分答案,贪心。 思路 我们在读入数据后首先要将任务序列按照 \(s\) 升序排序,因为我们需要优先完成时间紧迫(即完成时间靠前)的任务。随后我们可以开始进行二分答案了。令左边界 \(l=-1\),右边界 \(r=\max{s}\)。对于每一次二分出来的 \(mid\) 使用 check
阅读全文
摘要:本题做法 0-1 背包 DP。 思路 这题就是简单的 0-1 背包 DP 的小小变形而已。 我们可以定义 \(dp[i][j]\) 为前 \(i\) 个木石中剩余体力为 \(j\) 的最大填补体积。使用双重循环来递推 \(dp\)。若 \(j\ge m_i\),则 \(dp[i][j]=\max(d
阅读全文
摘要:本题做法 0-1 背包 DP。 思路 这道题是一道变形的 0-1 背包 DP 好题。 题目中说,砝码可以放在左边,也可以放在右边。我们令左盘的砝码重量始终大于或等于右盘的重量,设左盘的重量为 \(m_l\),右盘的重量为 \(m_r\),物品的重量为 \(m_t\)。则有: \[m_l=m_r+m_
阅读全文
摘要:本题做法 0-1 背包 DP。 思路 这道题是 0-1 背包 DP 的变种,与模板的区别就是价值等于代价。 其他的跟 0-1 背包 DP 的模板没什么区别的,直接按照模板打上去就行了。 代码 #include<bits/stdc++.h> typedef long long ll; typedef
阅读全文
摘要:本题做法 0-1 背包 DP。 思路 定义 \(dp[i][j]\) 表示在前 $i 首歌曲是否可以达到音量 \(j\)(是的话为 \(\text{true}\),否则为 \(\text{false}\))。因为音量 \(j\) 可以由音量 \((j+c[i])\) 降低 \(c[i]\) 或者由音
阅读全文
摘要:本题做法 完全背包 DP。 思路 这题可以转化成完全背包 DP 问题来解答。设 \(dp[i][j]\) 表示枚举到 \(i^4\) 时和为 \(j\) 的最少四次方数个数,则每个四次方数的本身可以抽象为物体的体积,每个物体的价值为 1。 由于 \(1\le m\le 10^5\),所以我们最多只需
阅读全文
摘要:本题做法 分组背包 DP。 思路 这题是经典的分组背包模板题。我们可以对每个物品的所属组和对每个组的物品数量及具体物品进行记录,因为每组至多只能选择 1 个物品,所以我们可以枚举组数的同时对当前组内的第几个物品进行枚举,然后接下来就和普通的 0-1 背包 DP 差不多了。 代码 #include<b
阅读全文
摘要:本题做法 模拟,two-pointers。 思路 首先因为题目中的项链是一个环形,而在环形上面处理问题是比较麻烦的,所以我们需要将环形转化为一条直线。我们可以将整个字符串复制一遍放在末尾,然后遍历开头为 \(i=1,2,\cdots, n\) 的项链(即第 \(i\sim i+n-1\) 个珠子)就
阅读全文
摘要:本题做法 区间 DP。 思路 这题我们可以用区间 DP 来求解。令 \(dp[i][j]\) 表示第 \(i\) 个零食到第 \(j\) 个零食所可以得到的最大价值,那么由于 \(dp[i][j]\) 可以由 \(dp[i+1][j]\) 和 \(dp[i][j-1]\) 转移而来(可以自己思考一下
阅读全文