主要记录模拟赛错题。
要查找某一天的记录,Ctrl+F 即可。
每次考试前看一遍!!!
P1722 矩阵 II #tag:8-10 下午测试 401
-
错误思路:brute-force。
-
正确思路:dp,令 \(dp_{i,j}\) 表示以 \(i\) 结尾放了 \(j\) 个红色算筹的方案数,初始 \(dp_{0,0}=1\),答案 \(dp_{2n,n}\)(因为最后红、黑色要一样多),转移 \(dp_{i,j}=dp_{i-1,j}+dp_{i-1,j-1}\)(\(i \in [1,2n],j \in [\lceil \frac{i}{2} \rceil,i]\)),因为红色算筹要比黑色多。
-
错误原因:一看到题就不自觉地往爆搜、模拟这方面想,没有牢记“求方案数又不输出方案,考虑 dp”。
P6188 [NOI Online #1 入门组] 文具订购 #tag:8-10 下午测试 401
-
错误思路:枚举 \(a,b,c\),选最优方案。由于计算 \(c\) 时会有浮点数误差,导致 WA。
-
正确思路:从大到小枚举成套数(共 \(\frac{n}{14}\) 套)。要求物品总数尽可能大,则尽量多买笔记本。若余数为 \(0\),直接加上能买的数量即可;若余数为 \(1\),退掉一本笔记本换一支笔即可;若余数为 \(2\),退掉两本笔记本换一支圆珠笔即可。
-
错误原因:没有考虑浮点数误差,也没有思考更简易的枚举方式。
-
总结:
-
尽量不要用到浮点数参与运算,能化成整数的就化成整数。
-
要训练自己往简洁的方式想。
-
当某题情况较少时,直接分讨。
-
P2678 [NOIP2015 提高组] 跳石头 #tag:8-10 下午测试 401
错误思路:二分,check 时只检查了相邻两块石头的距离是否小于 \(x\),是就移走当前石头。
正确思路:有可能移走当前石头后距离仍小于 \(x\),这时需要接着移。
错误原因:做过的题没有重复巩固。check 思路没有理清。以后记得在草稿上写好再敲代码。
P2040 打开所有的灯 #tag:8-10 下午测试 401
错误思路:dfs,没有标记。
正确思路:应当标记每个点,因为一个点只能开关至多一次,再多了就无效。
错误原因:没有想清楚所有要点就开写。
P2029 跳舞 #tag:8-10 下午测试 401
错误思路 / 原因:没写。
正确思路:dp,令 \(dp_{i,j}\) 表示以 \(i\) 结尾跳了 \(j\) 步的最大收益,初始 \(dp_{i,0}=dp_{i-1,0}-s_i\),答案 \(\max\{dp_{n,i}\}\),转移 \(dp_{i,j}=\max(dp_{i-1,j-1}+s_i,dp_{i-1,j}-s_i)\),当 \(j \bmod t=0\) 时,\(dp_{i,j}=\max(dp_{i-1,j-1}+s_i+b_i)\)。
总结:求最大收益又不输出方案,考虑 dp,要敢想、敢写 dp。
B3626 跳跃机器人 #tag:8-17 下午测试 401
错误思路:dp,但题目有后效性。
正确思路:bfs。
总结:想 dp,先要考虑先决条件:是否有后效性 / 最优子结构。
B3618 寻找团伙 #tag:8-17 下午测试 401
错误思路:dfs,但写得过于复杂导致莫名错误。
正确思路:dfs,将每个人的能力表示为二进制数,则权重之和即为所有人的异或和。
总结:
-
看到二次幂,想到二进制表示。
-
看到奇为 \(0\),偶为 \(1\),想到异或。
-
还是要训练自己不断往简洁的方面想。
P3612 [USACO17JAN] Secret Cow Code S #tag:8-17 下午测试 401
错误思路:brute-force。
正确思路:因为字符串每次都是复制出来的,所以第 \(n\) 个字符一定能对应到第一个字符串的某个字符。于是递归分段处理(实现不能用真的递归,常数会很大),\(n<\frac{len}{2}\) 直接继续,\(n>\frac{n}{2}\) 则判断是否为第一个字符,若是则 \(n=\frac{len}{2}\),否则 \(n=n-\frac{len}{2}-1\)(\(n\) 表示当前下标,\(len\) 表示当前长度)。
总结:
-
处理字符串复制的题目,考虑递归分段处理。
-
实现时不能用递归,常数很大。
P2072 宗教问题 #tag:8-17 下午测试 401
错误思路:没写。
正确思路:dp,令 \(dp_i/f_i\) 表示以 \(i\) 结尾的最少集体数 / 最小危险值。初始 \(dp_0=f_0=0\) 其余 \(\infty\)。转移 \(dp_i=\min(dp_j+1,dp_i),f_i=\min(f_j+cnt,f_i)\)(\(cnt\) 表示当前 \(i \sim j\) 的宗教种类数,转移时顺便维护即可),注意 \(j\) 需要倒序 \(i \to 1\) 枚举,因为正序枚举可能没到 \(i\) 时 \(cnt\) 就大于 \(k\) 了,从而没有转移。答案:\(dp_n,f_n\)
总结:
-
最值问题想 dp。
-
注意诸如循环顺序这种细节。
P1326 足球 #tag:8-17 下午测试 401
错误思路:没写。
正确思路:结论题。要求赢的分最大,则只可能输一场或不输(不输要满足 \(s \ge t\)),输的分最大同理,也只能赢一场或不赢(不赢要满足 \(t \ge s\)),分讨即可,具体见代码。
总结:看到 \(10^9\) 数据范围,考虑是不是结论题。
P2207 Photo #tag:8-17 下午测试 401
错误思路:没写。
正确思路:我们可以把问题想像成拍了一张 \(1 \sim n\) 区间的照片,再在中间分割,求分割的最小次数,这便转化为了区间选点问题。对于每个分割点,我都想使其被更多的区间包含,这样分割点会更少。于是我们将区间按右端点从小到大排序,每次选右端点前面那个即可(不能选右端点不然分了等于没分)。
总结:学到了区间选点模型,以后看到区间问题可以尝试将其转化为此模型。
P4379 [USACO18OPEN] Lemonade Line S #tag:8-18 下午测试 401
错误思路:没写。
正确思路:贪心,将每头牛按 \(a_i\) 从大到小排序,依次放置奶牛到队列即可。从大到小排序是因为 \(a_i\) 更大的奶牛更容易进队,从而使后面 \(a_i\) 小的奶牛更不容易进队,使得队列牛数更小。
总结:
-
求最值问题,考虑 dp 未果,或感觉比较神秘的,考虑贪心。
-
考虑贪心,先考虑排序。
P3817 小A的糖果 #tag:8-18 下午测试 401
错误思路:对于每对 \(a_i,a_{i+1}\),若 \(a_i+a_{i+1}>x\),则对 \(a_{i+1}\) 进行操作。
错误原因:\(a_{i+1}\) 可能不够减,并且没开 long long
。
正确思路:\(a_{i+1}\) 不够减就减 \(a_i\)。
总结:以后要仔细考虑特殊 / 边界情况,并多用边界数据进行测试。
P2772 寻找平面上的极大点 #tag:8-18 下午测试 401
错误思路:brute-force。
正确思路:按 \(x\) 为第一关键字,\(y\) 为第二关键字排序。对于每个点,只有它前面的点才有可能支配它,而他们的 \(x\) 一定大于当前点的 \(x\)。动态维护 \(y\) 最大值并比较即可。
总结:以两维作条件的题,可以固定一维,再处理另一维。
P1394 山上的国度 #tag:8-18 下午测试 401
错误思路:没写完。
正确思路:用并查集双向合并再判断所有点是否在一个集合即可。注意合并时只有 \(u\) 与 \(v\) 的根可以流通,并不代表 \(u\) 的根与 \(v\) 的根也可以流通。
总结:并查集不能一味照板子写,要思考哪里变化了。其他算法也是。
P1395 会议 #tag:8-18 下午测试 401
错误思路:没有输出编号最小的。
正确思路:用 vector
记录重心并排序。
总结:审题很重要。
P2240 【深基12.例1】部分背包问题 #tag:8-19 下午测试 401
错误思路:贪心,但是排序时 cmp 写成了除法导致精度误差,并且没有判断最后是否满了就直接加。
正确思路:贪心,按性价比(即单位价格)排序即可。这是因为分割金币以后性价比不变,选性价比更高的一定更优。
总结:
-
慎用除法、浮点数,避免精度误差!!!
-
思路一定要先打好草稿!!!!!
P5650 基础字符串练习题 #tag:8-19 下午测试 401
错误思路:brute-force。
正确思路:\(1\) 转成 \(-1\),\(0\) 转成 \(1\),然后跑最大子段和。
总结:要牢记最大子段和的套路。
P6023 走路 #tag:8-19 下午测试 401
错误思路:没写。
正确思路:结论题。对于任意两天,设它们走的步数,已经获得的分数以及接下来每步可得的积分分别为 \(a_1,a_2,b_1,b_2,c_1,c_2\),不妨设 \(c_1 \ge c_2\),则显然我们有 \(b_1+a_2 \times c_1 \ge b_1+a_2 \times c_2 \ge b_1+b_2\)。(\(a_2 \times c_2 \ge b_2\) 是因为后面可能还有激励)。于是我们发现将所有步数放在一天走完即可达到最优。
总结:看到极大数据范围,考虑结论题。
P6014 [CSGRound3] 斗牛 #tag:8-19 下午测试 401
错误思路:brute-force。
正确思路:枚举两个数的余数,易得若存在 \(n-2\) 个数的和为 \(10\) 的倍数,则总点数之和一定与剩下两个数的和在模 \(k\) 意义下同余。根据这个判断即可,具体见代码。
总结:做题找数据范围小的地方入手(本题余数只有 \(1 \sim 10\))。
P2420 让我们异或吧 #tag:8-19 下午测试 401
错误思路:没写完。
正确思路:倍增维护树上前缀和即可(就是预处理 LCA 的部分顺便维护即可)。
B3828 [NICA #2] 优秀正整数 #tag:8-20 下午测试 401
错误思路:枚举 \(i\),判断 \(i \times i\) 是否为优秀正整数即可。
正确思路:同错误思路。
错误原因:取模次数太少。
总结:要取模的题,每一步都得取模。
P1878 舞蹈课 #tag:8-20 下午测试 401
错误思路:没写。
正确思路:用小根堆维护每一对跳舞的人即可,具体实现细节见代码。
总结:想出 brute-force 之后,要思考哪部分可以优化,再选较容易优化的部分优化。如这题就是选绝对值最小的可以用小根堆维护。
P6092 [CEOI2012] 工作规划 #tag:8-20 下午测试 401
错误思路:没写。
正确思路:二分所需机器数,若没安排完且当前机器不会超时就安排上,否则取完成任务时间最靠前的机器做(前提是也不超时)即可,其中第二个过程可以用小根堆维护。
总结:二分 + 贪心 以及 小根堆优化 都是普及组模拟赛的参考点,必须牢记。
B3752 [信息与未来 2019] 新斐波那契数列 #tag:8-22 下午测试 401
错误思路:没写。
正确思路:发现所有新斐波那契数列里的数都可以表示为形如 \(k \times a+c\) 的表达式,然后又发现项数大约是 \(\log\) 级别的,于是枚举 \(n\),递推计算 \(k_i,c_i\),若当前 \(n\) 满足 \(k_n \times a+c_n=x\),则输出即可。
总结:\(10^9\) 数据范围,考虑数学结论!!!(找规律)
P8669 [蓝桥杯 2018 省 B] 乘积最大 #tag:8-22 下午测试 401
错误思路:dp,但没有最优子结构。
正确思路:贪心,\(k\) 为偶数就两个两个选,每次看选两正数还是两负数哪个更大。为奇数时,若最大的一个是正数则直接选它,否则说明全是负数,每次选两个时要比较哪个更小(因为第一个数是负数)。
总结:
-
dp 要考虑先决条件。
-
dp 不行时就考虑贪心。
P1141 01迷宫 #tag:8-22 下午测试 401
错误思路:dfs 找联通块,但是看错题了,以为是 \(n \times m\) 的矩阵。
正确思路:同错误思路。
总结:审题!!!把题目条件列在草稿纸上。
P2700 逐个击破 #tag:8-22 下午测试 401
错误思路:对于每条连接敌对城市的边断掉。但是有可能存在比该边更小的边,断掉它以后两个敌对城市也不在一个联通块里了。这很容易 hack。
正确思路:容易发现将 \(k\) 个敌对城市不联通,需要断掉 \(k-1\) 条边。考虑将边按边权从小到大排序,依次考虑所有边并尝试断掉,同时使用并查集维护联通性。但是并查集不支持删除,于是正难则反,将边按边权从大到小排序,考虑加 \(n-k\) 条边即可。
总结:学到了正难则反思想。
B3694 数列离散化 #tag:8-23 下午测试 401
错误原因:没开 map
。
总结:考试一定要留出 \(15\) 分钟检查。
P2802 回家 #tag:8-23 下午测试 401
错误思路:纯 DFS。
正确思路:DFS + 剪枝,或 BFS。
总结:搜索尽量用 BFS,用 DFS 就一定得剪枝。
P2085 最小函数值 #tag:8-23 下午测试 401
错误思路:枚举 \(x\),每次取 \(F_i(x)\) 的最小值,但是这是错的,因为假设第一轮选了 \(F_3(1)\),但有可能存在 \(F_i(1)<F_3(2)\) 且 \(i \neq 3\),因此不能直接跳过。
正确思路:用优先队列维护 \(F_i(x)\) 的最小值,每次弹出队头,并插入下一个即可。
总结:当觉得问题过于简单时,想一想是不是错了。
P1661 扩散 #tag:8-23 下午测试 401
错误思路:floyd,但是抄板子。
正确思路:floyd / 二分 + dsu。
总结:不能一味抄板子,要想想哪里要改动的。
P1658 购物 #tag:8-23 下午测试 401
错误思路:dp。
正确思路:贪心。
很容易发现我们第一个一定选 \(1\),如果连 \(1\) 都不选,那么 \(1\) 一定凑不出,于是无解。
接着手玩:
1 1 -> 1 2
1 2 -> 1 2 3
1 3 -> 1 3 4
我们发现,前两组都能凑出连续的数,到第三组就凑不出了。
这是因为 \(3>2\),因此 \(2\) 无法被凑出。
更一般的,我们发现,令 \(sum\) 表示目前序列长度,则若当前要添加的数 \(> sum+1\),则一定不行,否则一定可以。
继续,对于可行的数,它们对序列长度的贡献即为他们本身。
于是我们将 \(a[]\) 排序,每次从大到小枚举直到可行,然后添加之即可。
总结:dp 不行想贪心,贪心就要玩样例。
P1165 日志分析 #tag:8-24 下午测试 401
错误思路:优先队列 + 栈,待查错。
正确思路:维护 \(dp_i\) 表示栈顶编号 \(i\) 的最大值,每次 \(dp_i=\max(dp_{i-1},x)\)(\(x\) 为插入的数)即可。
总结:对于普及组数据结构题,考虑维护前缀和 / 积 / 最值等等。
P1258 小车问题 #tag:8-24 下午测试 401
错误思路:推式子,但是推错了。
正确思路:二分第一个人坐车到的点,再计算两人分别到达目的地的时间,若第一个人时间 \(>\) 第二个人时间则它要坐少一会车,猜小,否则猜大即可。
总结:对于数学问题(特别是这种行程问题),一定要画图再推式子。如果推出来的式子太复杂,则要审视是否错了。
P2193 HXY和序列 #tag:8-24 下午测试 401
错误思路:dfs。
正确思路:dp,令 \(dp_{i,j}\) 表示以 \(i\) 结尾最后一个数选了 \(j\) 的方案数。初始:\(dp_{1,i}=1\),答案:\(dp_{n,i}\),转移:\(dp_{i,j}=dp_{i,j}+dp_{i-1,k}\)(\(k\) 为 \(j\) 的因数)。
总结:能 dfs 的,一般能 dp。求方案数,想 dp。
P3915 树的分解 #tag:8-24 下午测试 401
错误思路:没写。
正确思路:维护子树大小,等于 \(k\) 的就切掉,最后判断 \(siz_1\) 是否为 \(0\) 即可。
总结:要敢想敢写。感觉是对的就一定先写,不要犹豫。
P1589 泥泞路 #tag:8-25 下午测试 401
错误思路:模拟,若上次长度有余数则当前长度 \(-1\),若有重叠则减重叠部分。但是这一次的起点应该是上一次实际的终点(不一定是输入的,因为可能有余数),我没有记录。
正确思路:记录这个即可。
总结:这题有三种情况:全包含、有重叠、无重叠。写代码之前应当把这三种情况一一列举出来分别考虑,并且注意有余数、记录实际终点等细节。总之,要勤动笔,尤其是这种模拟题。
P3913 车的攻击 #tag:8-25 下午测试 401
错误思路:记录每行、列是否计算过,没有就加 \(n-1\),否则加 \(1\),但是有可能某个车的位置会算多次。
正确思路:整体思想,将行、列去重,得到总个数 \(x,y\),则答案即为 \((x+y) \times n-x \times y\)。
总结:单独难以处理时,考虑整体处理。
P2694 接金币 #tag:8-25 下午测试 401
错误思路:没有考虑要等金币落下的情况。
正确思路:考虑即可。
总结:打草稿!
B3874 [GESP202309 六级] 小杨的握手问题 #tag:8-25 下午测试 401
错误思路:树状数组求正序对,但是没开 ll。
正确思路:开 ll 即可。
总结:逆序对开 ll!
P3884 [JLOI2009] 二叉树问题 #tag:8-25 下午测试 401
错误思路:求 LCA 写挂了,第一次跳的时候没有让 \(x,y\) 跳到同一层(即写成了 dep[dp[x][i]]>dep[y]
)。
正确思路:改成 >=
即可。
总结:LCA 板子背的不熟。还得背几遍。
P2782 友好城市 #tag:8-25 下午测试 401
错误思路:没写。
正确思路:\(O(n \log n)\) 求最长上升子序列的板子。维护 \(dp_i\) 表示以 \(i\) 结尾的最长上升子序列的最小末尾值,对于每个 \(i\),二分出最小的满足 \(dp_x < y_i\) 的最小 \(x\),其中 \(y_i\) 为北岸友好城市的坐标(因为 \(dp_x\) 单调递增,因此可以二分),尝试让 \(y_i\) 接在 \(dp_l\) 后面并更新最长上升子序列的长度即可。
P1464 Function #tag:9-25 下午测试 401
错误思路:对于读入结束的条件判断错误(写成了 a!=-1&&b!=-1&&c!=-1
)。
总结:审题!!!以后防范此类错误的发生。
P1095 [NOIP2007 普及组] 守望者的逃离 #tag:9-25 下午测试 401
错误思路:没写。
正确思路:对于全用闪烁魔法的情况做一遍 dp,然后看是否能增加一些跑步来使行走的路程更长。
总结:对于这种有多种情况的 dp,可以先全使用一种,再在此基础上考虑另一种。
P1334 瑞瑞的木板 #tag:9-25 下午测试 401
错误思路:直接按木板长度从大到小排序,然后依次切割。
错误原因:不一定当前的木板就是最长的,有可能其余更小的木板拼成的长木板比当前木板更长。
正确思路:将合并果子的套路反过来就成了本题。
总结:合并果子的套路十分常见,以后遇到合并 / 拆分且价值 / 体力是两个元素的和的题,考虑这种套路。
P1363 幻象迷宫 #tag:9-25 下午测试 401
错误思路:搜索,若将地图内的点全走完就判定为合法。
错误原因:显然很容易被 hack。
正确思路:因为矩阵是重复的,所以考虑多带两个参数,即当前矩阵的编号 \((xx,yy)\),若能走到了一个点,它已经被走过且与上次到达的矩阵编号不同,说明它绕了一圈回到了原点,即为合法。
总结:想出了一个思路必须尝试证明,对于这种显然错误的思路就不要再尝试写出来了。
P1348 Couple number #tag:9-26 下午测试 401
错误思路:没写。
正确思路:
当 \(x,y\) 奇偶性不相同时,\(x+y,x-y\) 都为奇,乘起来也为奇。
否则,\(x+y,x-y\) 都为偶,乘起来为 \(4\) 的倍数。
综上,当 \(n\) 为奇数或为 \(4\) 的倍数时,它就是 Couple number。
总结:对于这种式子要更敏感一些,然后尝试从奇偶性发现规律。再不行还可以打表。
P1403 [AHOI2005] 约数研究 #tag:9-26 下午测试 401
错误思路:写了一个若至状压 + 组合数学,因为时间复杂度分析错误,沦为与暴力老哥同分 /ll。
正确思路:容易发现每个数 \(i\) 在 \(1 \sim n\) 中都有 \(\lfloor \frac{n}{i} \rfloor\) 个数能整除它,这便是 \(i\) 对于答案的贡献,累加即可。
总结:对于自己想出来的思路,要仔细验证正确性与时间复杂度。同时对于求和类题目,可以考虑换一种角度并采用算贡献思想。
P3737 [HAOI2014] 遥感监测 #tag:9-26 下午测试 401
错误思路:按横坐标排序,每次选取横坐标差值不超过 \(r\) 的点,取它们横坐标的中位数。
错误原因:横坐标差值不超过 \(r\) 不代表就能观测到,必须两点间距离不超过 \(r\)。
正确思路:区间选点,求出每个点能被观测到的放置区间,按照右端点排序(为了保证接下来只要考虑上次选的点),每次若上次选的点不能覆盖当前区间就选右端点即可(因为最有可能覆盖之后的区间)。
总结:对于区间覆盖问题,一定要考虑区间选点模型!!!
P1404 平均数 #tag:9-26 下午测试 401
错误思路:暴力。
正确思路:因为若存在某个区间的平均数为 \(x\),则所有 \(\le x\) 的平均数都是合法的,存在单调性,考虑二分。若区间 \([l,r]\) 的平均数为 \(x\),则有 \(\frac{\sum^r_{i=l} a_i}{r-l+1} \ge x\),转化一下可得 \(\sum^r_{i=l} (a_i-x) \ge 0\),于是枚举 \(r\),动态维护前缀和 \(s_i\) 以及与 \(r\) 相隔至少 \(m\) 且最小的 \(s_{l-1}\)(维护最小的是为了让区间和最大),每次判断 \(s_r-\min\{s_{l-1}\} \ge 0\) 即可。
总结:关于平均数的题,考虑推式子以及二分。
P1385 密令 #tag:9-26 下午测试 401
错误思路:没写。
正确思路:首先求方案数考虑 dp。然后发现不好 dp,于是发掘性质,发现字典序总和不变。于是多带一维,令 \(dp_{i,j}\) 表示长度为 \(i\) 且字典序总和为 \(j\) 时的方案数。答案就是 \(dp_{n,all}\)(\(all\) 为原字符串的字典序总和),初始状态就是 \(dp_{1,i}=1\)(长度为 \(1\) 时无法操作),转移就是 \(dp_{i,j}=dp_{i,j}+dp_{i-1,j-k}\)(\(k\) 是其中一个字母的字典序)。
总结:求方案数考虑 dp!!!当不好 dp 时,尝试发掘性质,增加维度。
B3958 [GESP202403 四级] 相似字符串 #tag:9-27 下午测试 401
错误原因:认为 insert
是在后面插入,实则是在前面插入。
错误思路 & 正确思路:过于简单,略。
总结:记住这个函数的用法即可。
P2239 [NOIP2014 普及组] 螺旋矩阵 #tag:9-27 下午测试 401
错误思路:暴力,还打挂了。
正确思路:将整个矩阵分为 \(n\) 圈,对于每个圈单独处理,具体见代码。
总结:对于此类无法直接模拟的模拟题,考虑分段找规律。然后平时做题要多训练自己打部分分的能力。
P2009 跑步 #tag:9-27 下午测试 401
错误思路:没写。
正确思路:floyd 板子。
总结:每个题最多想 15 min,注意时间分配。
P10725 [GESP202406 八级] 最远点对 #tag:9-27 下午测试 401
错误思路:暴力,还打挂了。
正确思路:这个题目求的东西很像直径,于是我们效仿直径的求法,直接找出以最深黑点与以最深白点为端点的最长链,取最大值即可。
总结:LCA 板子要多打!!!然后要思考题目的本质是什么。
U367566 咖啡牛奶 #tag:10-2 上午测试 401
错误思路:没写。
正确思路:看到 \(10^9\) 且无明显结论,考虑二分答案。判定时咖啡、牛奶先各分配 \(x\) 个,然后每种只要两个两个分配就能分配出若干套,计算套数是否 \(\ge x\) 即可。
总结:上述加粗的文字。
U367567 旅行计划 #tag:10-2 上午测试 401
错误思路:暴力建边跑最短路。
正确思路:考虑到是依次访问 \(1 \sim n\),考虑 dp(因为有了转移顺序),每次转移从上一个点直接走过来或者走到离它最近的传送门然后传送过来这两种方案中取最小值即可。
总结:对于一个题目,首先写下暴力方法,然后比对题目,发现题目的特殊之处,从这里着手进行优化。
U475307 逃跑 #tag:10-2 上午测试 401
错误思路:bfs,但是没有考虑直接走的情况。
正确思路:考虑一下直接走的情况即可。
总结:情况要考虑周全,尽量写到纸上。
U367568 全等序列 #tag:10-3 下午测试 401
错误思路:没写,但想到了判无解的情况。
正确思路:每次 \(+1-1\) 总和不变,因此最后每个数都应该是序列的平均数。于是若平均数不是正整数就无解。否则,从头开始枚举每一对相邻的数,用 \(a_{i+1}\) 去补上 \(a_i\) 的空缺 / 用 \(a_i\) 去补 \(a_i\) 的空缺即可。
为什么必须从头开始,枚举?
若从 \(i(i \neq 1)\) 开始枚举,分两种情况:
\(1 \sim i\) 的平均数等于全局平均数:
则该情况等价于从 \(1\) 开始枚举。
\(1 \sim i\) 的平均数不等于全局平均数:
则意味着从 \(i\) 枚举完一遍之后还得从 \(1\) 开始枚举一遍以使全都相等,这还不如直接从 \(1\) 开始枚举更优。
综上,必须从头开始枚举。
总结:想到了一步就要大胆猜想、往下推进,不能止步不前。
U475121 蹦床 #tag:10-3 下午测试 401
错误思路:没写。
正确思路:尝试以每个点作为起点,然后模拟跳跃过程即可。
总结:普及组的题目,都可以考虑模拟思想。
U475301 分数获取 #tag:10-3 下午测试 401
错误思路:没写。
正确思路:\(sum_r-sum_{l-1}=r-l+1 \to sum_r-r=sum_{l-1}-l\),用 STLmap 标记每个 \(s_i-i\) 并查询有多少个与当前相等的即可。
总结:区间计数,考虑推式子 + map 标记。
P1435 [IOI2000] 回文字串 #tag:10-3 下午测试 401
错误思路:没写。
正确思路:两端类区间 dp,令 \(dp_{i,j}\) 表示区间 \([i,j]\) 的最小操作次数,答案 \(dp_{1,n}\),初始 \(dp_{i,i}=0\),转移:若 \(s_l=s_r\) 且长度为 \(2\),\(dp_{l,r}=0\),长度不为 \(2\) 则 \(dp_{l,r}=dp_{l+1,r-1}\);否则从 \(\min(dp_{i+1,j}+1,dp_{i,j-1}+1)\) 转移过来。
总结:回文类问题,考虑两端类区间 dp。
P1293 班级聚会 #tag:10-9 下午测试 401
错误思路:没有考虑“花费相同时优先取靠近莫斯科的城市”。
正确思路:略。
总结:审题!!!题目特殊要求
写纸上。
P1689 方程求解 #tag:10-9 下午测试 401
错误思路:没有考虑空格在数字中间的情况。
正确思路:略。
总结:模拟题要写数据生成器以便考虑到边界情况。
P2105 K皇后 #tag:10-9 下午测试 401
错误思路:正对角线的判定应当是 \(x-y+n\) 相等,不是 \(\mid x-y \mid\) 相等(有可能会将两条不同的对角线当作一条)。
正确思路:略。
总结:牢记正对角线的判定方法即可,比较常用。
P10111 [GESP202312 七级] 纸牌游戏 #tag:10-9 下午测试 401
错误思路:令 \(dp_{i,j}\) 表示表示前 \(i\) 轮换了 \(j\) 次牌能获得的最大分数,枚举上次换牌的那一轮,从那里转移。
错误原因:有可能不换牌。
正确思路:令 \(dp_{i,j,k}\) 表示前 \(i\) 轮换了 \(j\) 次牌且当前选的是 \(k\) 颜色能获得的最大分数;初始化第一轮,其余极大值;答案为 \(\max\{dp_{n,i,j}\}\);转移分第 \(i\) 轮换 / 不换牌转移即可,具体见代码。
总结:设状态应该把所有我们关心的量都设进去,并且不一定是枚举转移点转移,一般都是从上一个转移。
P1827 [USACO3.4] 美国血统 American Heritage #tag:10-10 下午测试 401
错误思路:没错,只是代码实现没想清楚,导致写的太复杂了。
正确思路:每次在前序遍历中找当前子树的根节点,然后找到其在中序遍历中的位置,劈成左右两个子树,分别递归下去即可。需要维护中序遍历的区间以及前序遍历中的对应区间。输出后序遍历可以在递归结束后顺便完成。
总结:写代码前一定要对自己没有把握的题进行代码设计,力求简洁,察觉到想的太复杂就立马换一种。然后这是一个经典问题,这种确定后序遍历的方法需要记住。
B3968 [GESP202403 五级] 成绩排序 #tag:10-10 下午测试 401
错误思路:没错,代码没有从在线 IDE 拷贝回来,并且打错了一个字母导致保龄,难绷。
正确思路:略。
总结:下次修改的每一个版本都要及时拷贝回来。然后写完一个题要花个 \(5\) 分钟进行静态查错,防止类似情况的发生。
P8703 [蓝桥杯 2019 国 B] 最优包含 #tag:10-10 下午测试 401
错误思路:\(S\) 掐头去尾之后求与 \(T\) 的 LCS,再用 \(T\) 的长度减去它就是答案。
错误原因:有可能 \(S_n=T_m\),结果掐头去尾之后发现要修改一个字符,实际上一个都不要修改。
正确思路:见我的 TJ。
总结:这种题老老实实按部就班地 dp,不要想其他的。
P6365 [传智杯 #2 初赛] 众数出现的次数 #tag:10-14 下午测试 401
错误思路:没写,以为是 dp。
正确思路:直接开个 map 统计出现最多的数即可,注意同一张卡出现了相同的 \(a_i,a_i \operatorname{xor} b_i\) 只要统计一次。
总结:做题应该尽量往简单的方面想。
P8673 [蓝桥杯 2018 国 C] 迷宫与陷阱 #tag:10-14 下午测试 401
错误思路:bfs,但是走过的点就不能走。
错误原因:通过样例一可知是可以重复走的。
正确思路:应该改为走过去时无敌次数比之前少的格子不能走。
总结:带有其他条件(如:生命值、无敌次数等)的 bfs,考虑最优性剪枝(比之前走到时更少就不走)。
P4715 【深基16.例1】淘汰赛 #tag:10-14 下午测试 401
错误思路:纯模拟,但是常数太大导致 T 飞。
正确思路:前半部分的最大值和后半部分的最大值的最小值即为答案。
总结:少用 memset,memcpy
,然后对于纯模拟想想可不可以优化。
P8642 [蓝桥杯 2016 国 AC] 路径之谜 #tag:10-14 下午测试 401
错误思路:没写。
正确思路:把射箭看成拔箭即可 dfs(其实正着做也可)。
总结:看到此类问题直接想 dfs / bfs,两种都要想一想。
P8200 [传智杯 #4 决赛] 生活在树上(easy version)#tag:10-14 下午测试 401
错误原因:没开 unsigned long long
。
总结:以后直接 #define int xxx
,不要单独开,以免漏掉变量。
P8661 [蓝桥杯 2018 省 B] 日志统计 #tag:10-15 下午测试 401
错误思路:没写。
正确思路:单调队列维护所有形如 \([T,T+D)\) 的区间,并统计当前插入的元素出现次数是否 \(\ge k\),是则该帖是热帖。至于为什么只需要枚举当前帖子前面的帖子,这是因为如果后面的区间能满足要求,则说明后面有多了几个与当前编号相同的帖子,但是枚举到它们的时候就能一并统计了,不需要再枚举后面的。
总结:看到维护定长区间的信息的问题,考虑单调队列。注意使用的时候需要保持元素的单调性(此题中是将时间排序)。
P8648 [蓝桥杯 2017 省 A] 油漆面积 #tag:10-15 下午测试 401
错误思路:没写。
正确思路:扫描线 /fn。
P8783 [蓝桥杯 2022 省 B] 统计子矩阵 #tag:10-15 下午测试 401
错误思路:暴力。
正确思路:因为元素都是非负整数,矩阵元素和具有单调性,于是考虑框定左右边界之后,双指针维护上下边界即可,具体见代码。
总结:单调性是个很重要的性质,当只会暴力时考虑去发现单调性。然后这个性质不止可以用于二分,双指针、单调栈 / 队列也可以。
P6366 [传智杯 #2 初赛] 特殊的翻转 #tag:10-15 下午测试 401
错误思路:dfs。
正确思路:考虑贪心,我们一步一步地将前面的字符变为 \(0\),那么对于每个 \(1\),我们就只能变换它后面的字符而不能变换它本身,因为这样就会扰乱前面的操作。这样下来,除了第一个字符,其他字符的操作是确定的,于是枚举第一个字符如何操作即可。注意 \(16\) 转 \(2\) 进制不能通过 \(10\) 进制转,会爆。
总结:对于序列操作题目,感觉只能 dfs 的,考虑逐位操作以确定操作序列。
P10904 [蓝桥杯 2024 省 C] 挖矿 #tag:10-16 下午测试 401
错误原因:没判越界。
总结:注意 corner case!!!比赛还剩 15 min 时静态查错!!!
P8809 [蓝桥杯 2022 国 C] 近似 GCD #tag:10-16 下午测试 401
错误思路:没写。
正确思路:对于一个子数组,如果其中每个元素都是 \(g\) 的倍数,那么这个子数组的近似 GCD 一定为 \(g\)。这是因为,每个元素一定拥有 \(g\) 这个公约数,把其中一个改为 \(g\) 即可。同理,有且仅有一个数不是 \(g\) 的倍数的子数组也可。于是令 \(b_i=[a_i \bmod g \neq 0]\),求一遍 \(b_i\) 的前缀和得到 \(s_i\),然后对于每个 \(i\) 去寻找在他后面的且满足 \(s_j-s_{i-1}>1\) 的 \(j\),他对答案的贡献即为 \(j-i-1\)(\(j\) 不能算,并且区间长度要 \(>1\))。
总结:对于一眼困难题,找结论。
P8628 [蓝桥杯 2015 国 AC] 穿越雷区 #tag:10-16 下午测试 401
错误原因:bfs 不一定第一次走 +
。
总结:静态查错!!!
P6397 [COI2008] GLASNICI #tag:10-16 下午测试 401
错误思路:中位数。
错误原因:不一定中位数不动就是最优的,无法证明。
正确思路:考虑到时间越长,知道消息的信使越多,直接二分时间。因为一开始只有 \(1\) 知道信息,于是让所有人都和 \(1\) 相向而行,每次与两个人相距不超过 \(k\) 时,\(1\) 就「瞬移」到那个人的位置继续跑即可。这样就实现了信息一个一个传递的过程。
总结:将题目转化为线性模型逐个处理会更简单,尤其是二分的 check
部分。
P10902 [蓝桥杯 2024 省 C] 回文数组 #tag:10-17 下午测试 401
错误思路:没写。
正确思路:容易想到将前半部分逐个操作为后半部分,对于每一个数,考虑自己操作或者被前面的带着操作即可,具体见代码。
总结:操作题考虑逐位处理。
P7305 [COCI2018-2019#1] Cipele #tag:10-17 下午测试 401
错误思路:打了 \(M=N\) 的部分分,就是二分答案然后一一配对即可,结果反向挂了 \(27\) 分 qwq。
正确思路:稍加分析可以发现一定是丑陋度小的配小的,大的配大的,不会有交叉,因为交叉会使得两对都增大差值。于是对于每个数,不停往后找到它可以配对的第一个位置,然后进行配对即可。
总结:二分的 check
总是运用到贪心思想,思考的时候要尽量往贪心的方面想,然后再去证明。然后想到的每一个点子都要及时记录下来去实践一下。
P8708 [蓝桥杯 2020 省 A1] 整数小拼接 #tag:10-17 下午测试 401
错误思路:暴力。
正确思路:显然所有数排序之后每个数越往后越不可能拼出 \(\le K\) 的整数,具有单调性,考虑双指针。于是不断地往前找每个数后面最大的那个和它拼起来 \(\le K\) 的下标 \(r\),然后计算贡献即为 \(r\),注意如果 \(r\) 在当前的下标后面则不能算上当前的这个。
总结:只能打暴力的时候注意发掘单调性!!!
P8725 [蓝桥杯 2020 省 AB3] 画中漂流 #tag:10-17 下午测试 401
错误思路:暴力。
正确思路:dp。令 \(dp_{i,j}\) 表示走了 \(i\) 秒且剩余 \(j\) 体力的方案数,初始 \(dp_{0,m}=1\),答案 \(dp_{t,0}\),转移:当 \(D-i+2 \times (m-j)>0\)(即离峡谷还有 \(>0\) 的距离)时,\(dp_{i,j}=dp_{i-1,j}+dp_{i-1,j+1}\)(划或不划)。
总结:把想到的每一个点子都进行细致思考,不要浅尝辄止,并且这种求方案数的题基本就能考虑 dp 了。
P8663 [蓝桥杯 2018 省 A] 倍数问题 #tag:10-17 下午测试 401
错误思路:暴力。
正确思路:把每个数按照余数分为 \(k\) 类,只记录每一类的最大值,然后枚举两个数的余数,求出第三个数的余数然后求和取 \(\max\) 即可。但是有可能有重复余数,所以我们要记录前 \(3\) 大,对于三个数顺次分配,具体实现见代码。
总结:注意数据范围,通过数据范围可以看出做题的思路。然后此类求和取模的题目一般要想到按余数分类。
U475309 质数数量 #tag:10-18 下午测试 401
错误原因:没有考虑有多个 \(1\) 的情况。
正确思路:容易发现只有质数 $\times $ 若干个 \(1\) 才会对答案产生贡献。对于每个 \(1\),可以选 / 不选,于是答案即为质数个数 \(\times \ 2^{1 的数量}\),直接快速幂计算即可。
总结:多想想自己是否漏掉了情况,记得写拍子(或 gen)。
U475310 分糖果 #tag:10-18 下午测试 401
错误思路:暴力。
正确思路:容易发现最大值一定出现于 \(a_i+a_j<m\) 或 \(m \le a_i+a_j<2m\) 中(两个长 \(m\) 的区间),后者最大值一定为 \(a_i\) 的最大值加次大值,前者二分一下即可求出。
总结:余数问题考虑分类 / 分段处理。
U475311 字符串合并 #tag:10-18 下午测试 401
错误思路:暴力。
正确思路:区间 dp。令 \(dp_{a,b,c,d}\) 表示 \(S_{1_{a \sim b}}\) 与 \(S_{2_{c \sim d}}\) 是否能拼成回文串。初始:长度为 \(1\) 的为 \(1\),否则为 \(0\)。答案:所有为 \(1\) 的状态的区间长度取 \(\max\)。转移:分四种情况,\(S_{1_a},S_{1_b}\) 匹配、\(S_{2_c},S_{2_d}\) 匹配、\(S_{1_a},S_{2_d}\) 匹配、\(S_{2_c},S_{1_b}\) 匹配,具体见代码。
总结:回文类问题又满足 dp 特性的,考虑区间 dp。
U370872 对面的人 #tag:10-21 下午测试 401
错误原因:无解的情况少判断了 \(a,b,c\) 越界的情况。
总结:分情况的题一定要打草稿!!!
U373459 复制 #tag:10-21 下午测试 401
错误原因:见祖宗了。
总结:考前打缺省源!!!
U370874 K段区间 #tag:10-21 下午测试 401
错误思路:分出若干个递增序列,若每个序列中每两个数中间都没有其他数,并且恰好分出 \(k\) 个即为 YES
,否则为 NO
。
错误原因:想的太复杂,而且若中间有其他数时,完全可以从中间劈开,然后再插进去。
正确思路:直接构造递增序列,将整个数列排序,然后检查下标差值为 \(1\) 的有多少个序列,若其数量 \(\le k\) 即为 YES
(\(<k\) 的劈开即可),否则为 NO
。
总结:二维偏序问题,两个维度要分别考虑固定哪一维,哪种简单用哪种。
U372651 内存清理 #tag:10-21 下午测试 401
错误思路:暴力。
正确思路:考虑到 \(b\) 只有两种数值,不难想到二维偏序,枚举其中一种的选几个,然后二分另一种即可。
总结:多发现题目的特殊之处,然后两个东西就要想到二维偏序。
U370612 壁纸 #tag:10-22 下午测试 401
错误思路:dp,但是状态只设了一维,且转移方程条件错误,具体见错误代码。
正确思路:令 \(dp_{i,j}\) 表示第 \(i\) 天剩余 \(j\) 点吸引力的方案数。答案:\(\sum dp_{n,i}\)。初始:\(dp_{0,0}=1\)。转移:\(dp_{i,0}=dp_{i-1,0},dp_{i,j}=dp_{i,j}+dp_{i-1,j+1}(j>0),dp_{i,a_i}=dp_{i,a_i}+dp_{i,0}\)(当天要换壁纸,则当天上一张壁纸的吸引力必须为 \(0\))。
总结:状态设计尽量把所有信息都设进去,然后分情况转移。
U475118 六边形 #tag:10-22 下午测试 401
错误思路:没写。
正确思路:如果这个题只能上下左右走,那么直接朝着 \((x,y)\) 走即可,不会绕弯。但是这题可以斜着走,这样就有可能不朝着 \((x,y)\) 走反而更短,然后我们发现左上可以拆分为先左再上,右下可以拆分为先右再下,等等,每个方向都可以如此拆分,于是对于每一个方向取直接走和拆分走中更优的那个方案,这样直接朝着走就是最优的了(以上面的例子为例,如果先左上再右比先左再上更优,因为上被更新了,它可以拆分为左上+右,这样就是最优的了)。
总结:对于此类问题,我们一定要考虑直接朝着走最优,不是最优也要想办法将其变为最优(如拆分取最小值这种办法)。
U373462 划船 #tag:10-23 下午测试 401
错误思路:枚举和,然后双指针,但是只维护了右指针。
正确思路:令当前和为 \(s\),维护两个指针 \(l,r\),如果 \(w_l+w_r=s\),答案累加并同时移动左右;如果 \(w_l+w_r>m\),移动右指针(注:\(w\) 已排序);否则,移动左指针。最后对所有答案取 \(\max\) 即可。
总结:双指针一定要考虑维护两个指针,然后分情况移动。
U475104 猫猫 #tag:10-23 下午测试 401
错误思路:暴力。
正确思路:对于 \(n\) 为偶数,\(A,B\) 不会相遇,答案为 \((k-1) \bmod n+1\)(\(k-1\) 是为了平移区间方便取模);对于 \(n\) 为奇数,\(A,B\) 每走 \(\lfloor \frac{n}{2} \rfloor\) 就会相遇一次,然后 \(B\) 就会多走一步。于是答案即为 \((k-1+\frac{k-1}{\lfloor \frac{n}{2} \rfloor}) \bmod n+1\)。
总结:\(10^9\) 数据范围考虑结论题,然后画图分析。
U373463 宝可梦 #tag:10-23 下午测试 401
错误思路:没写。
正确思路:首先不考虑询问,我们直接交替找峰值与谷值即可。考虑询问如何解决:容易发现每次交换只会影响 \(x-1,x,x+1,y-1,y,y+1\) 这 \(6\) 个位置(其他的根本不会成为新的谷 / 峰),于是消除这些位置的贡献,再交换后依次增加即可,注意去重。
总结:最值相关问题要想到找谷 / 峰,然后询问操作要考虑是否只会影响到少部分位置。
U373025 回文序列 #tag:10-24 下午测试 401
错误思路:暴力。有点可惜,最关键的第一条性质想到了,差了临门一脚。
正确思路:不难发现,若删除一些 \(x\) 可使回文,则全删除也可使回文。到这里,一个很显然的暴力就出来了:枚举删哪一个数,然后判断其是否为回文(场上打的就是这个),可以获得 \(70 pts\)。接着我们容易看出暴力的瓶颈在于枚举选哪个数,这其中一定有不少非必要的枚举。考虑什么是必须要删的,经过手玩可以发现是第一个满足 \(i \neq n-i+1\) 的下标 \(i\) 与 \(n-i+1\)(因为前面的都是回文,所以无论怎么删其他数这两个数一定是对应的,只有删这两个数其中的一个才能使它们不对应),然后直接暴力删并判断即可。这个 T2 感觉放错位置了()
总结:想出了暴力算法之后,要思考瓶颈在哪里。然后减少枚举量的方法一般是考虑必要的枚举。
U496316 magic #tag:10-24 下午测试 401
错误思路:dp,但是没想出来。
正确思路:反悔贪心。维护一个小根堆记录使用魔法的建筑,首先将前 \(k\) 个加到里面去,然后一个一个看,若当前建筑高度大于堆顶高度,说明可以将堆顶的魔法转移到当前建筑来,然后减去堆顶体力值,否则直接减去当前体力值即可。维护小根堆是为了保证减少的体力尽可能小。
总结:dp 不行,考虑贪心 / 反悔贪心。然后把所有点子写下来,一个个深入思考。
U373029 聚会 #tag:10-24 下午测试 401
错误思路:暴力,还写挂了。
正确思路:二分最大人数(选了 \(x\) 人则一定能选 \(x-1\) 人),然后检查有多少个人满足要求,具体见代码。
总结:暴力题发掘单调性。