2025-04-13 15:27:30
深度优先搜索(DFS)是学生学习算法的第一道门槛,因为它的主要形式是递归。而递归中需要将搜索的相关信息通过参数传递,这一点需要学生深刻理解 DFS。
DFS 有比较标准的模版,如下所示:
1 |
void dfs(int pt) // pt 表示层数 |
我们将运用该模版,完成后面的题目。
递归的时候,程序会占用栈空间来保存函数的环境变量。根据编译器以及编辑参数的不同,栈空间的大小也不同。通常情况下,竞赛中的编译器设定的栈空间为 8M 或者 16M。
假如,我们在一个递归函数中使用了 10 个 int 变量,那么每个递归函数就需要 4*10=40
字节的栈空间。8M 一共可以支持 8*1000*1000/40=200000
层调用。考虑到栈空间还需要保存当前函数执行的地址等变量,可供支持的调用层数会更小一点。
同学们也可以做如下的递归函数栈空间的测试:
1 |
/** |
在我的本地,以上程序调用了约 13 万次后栈溢出。为了保险,我们在比赛中如果调用深度小于 1 万层,那应该是稳妥的;否则我们需要考虑是否用别的解法来解题。
题目名 | 说明 |
---|---|
P1036 选数 | NOIP 2002 普及组 |
P1219 八皇后 Checker Challenge | USACO 1.5 |
P1596 Lake Counting S | USACO10OCT |
P2036 PERKET | COCI 2008/2009 #2 |
P12139 黑白棋 | 蓝桥杯 2025 省 A,写起来较繁琐 |
P7200
P10483
这是八皇后的变种,N 皇后问题。可以作为基础练习。具体解法是:
v[15]
表示每个皇后的列值。1 |
bool check(int pt) { |
完整的代码如下:
1 |
/** |
此题需要从小到大取数求和,然后再判断是否是素数。用递归的方式来进行枚举。
1 |
/** |
此题既可以用 DFS,也可以用 BFS。考虑到 N 和 M 最大值为 100,所以递归的层次最多为 1 万层,所以我们可以试试 DFS。
以下是参考代码:
1 |
/** |
因为 N 最多为 10,每种食材可以选或者不选两种情况,所以最多情况数为 2^10=1024
种。搜索时间满足要求。
所以,此题用 DFS 可以非常方便解决。在搜索的时候,我们可以将食材的相关信息带到 DFS 函数的参数中,方便最后答案的求解。
1 |
/** |
此题是搜索题,需要在中间尽可能检查状态来剪枝,以节省搜索次数。
题目有三类限制,分别可以用在不同的剪枝环节。
限制一:在每一行和每一列中,黑色棋子和白色棋子的数量必须相等(即为 3)。
限制二:不能有超过两个相同颜色的棋子连续排列。
限制三:行列唯一性
另外,这个棋盘有几个位置已经设定了值,我们需要标记下来,搜索的时候跳过对这些位置的尝试,但需要在这些位置做合法性检查。
1 |
/** |
2025-04-12 22:00:46
先记录一下写作点:
__gcd
2025-04-12 21:40:39
数学题是信息学竞赛中重要的一类题目,通常包括几何、数论、容斥原理等。
本文将相关的题目归纳整理,用于教学。
本题解法:每个矩形(包括正方形)都可以由一段左边线段和一段上边线段确定。因此,我们只需要枚举所有可能的线段。
对于一个长是 N 宽是 M 的棋盘。
所以:
(1+2+3+...+N)= N*(N+1)/2
个。(1+2+3+...+M)= M*(M+1)/2
个。N*(N+1)/2 * M*(M+1)/2
个矩形。用相同的办法可以推导正方形的数量,方法如下:
N*M
个边长为 1 的正方形。同理:
(N-1)*(M-1)
个边长为 2 的正方形。以此类推,可以构造出 N*M + (N-1)*(M-1) + (N-2)*(M-2) + (N-M+1)*1
个正方形(N>M)。
另外,需要注意使用 long long
来保存结果。完整的代码如下:
1 |
|
2025-04-06 11:20:47
枚举就是把所有情况都尝试一遍。比较简单的用 for 循环即可,较复杂的枚举,需要用到递归。
此题直接枚举每个合数拆解成两个质数和的所有可能性。为了避免重复计算质数,我们用一个 map 将其运算结果保存下来。
1 |
/** |
此题初看起来 N 很大,但是每种配料最多 3 克,一共 10 种,总克数最多为 30 克。所以超过 30 克的情况答案都为 0。
每种配料 3 种情况,一共 10 种配料,所以暴力枚举的时间复杂度 3^10 约为 59000,不会超时。
枚举的参考代码如下:
1 |
/** |
全排列的问题有多种写法,此题可以直接用 STL 中的 next_permutation
函数。
1 |
/** |
其实组合也可以用 next_permutation
来实现。以 n=5,r=3 为例,具体方法是:
0 0 0 1 1
,这样对应输出的是 1, 2, 3
0 0 1 0 1
, 输出 1, 2, 4
1 1 0 0 0
,输出 3, 4, 5
以下是实现代码:
1 |
/** |
更多全排列的练习:
我们先预保存下来每行的各种颜色的色块数量,这样检查的时候就可以快速求解。
1 |
/** |
直接枚举每个起点。但是 k==1
时需要特判,因为 k==1
意味着向下和向右重复计算,需要除以 2。
1 |
/** |
2025-03-29 23:06:22
模拟是最有效的练习编程熟练度的基础算法,也是有效的掌握各种编程技巧的练习方式。
本文将把各种模拟技巧与题目结合,用题目带着学生掌握这些模拟技巧。
有些时候,我们在处理二维数组的时候,需要处理 x,y 坐标的边界。这样写起来会比较麻烦,但是,如果我们将数据从下标 1 开始保存,那么就人为在数据外面留了一圈缓冲带。这个时候,在处理 x,y 周围坐标的时候,就不会出现数据下标越界的情况了。
该题如果正常写,需要判断每个格子周围 8 个格子的状态。如果我们把数据从 1 开始读入,在判断的时候就容易很多。以下是参考代码。
1 |
/** |
本题也可以用包边的技巧,保证数据在检查的时候不会越界。参考代码如下:
1 |
|
此题需要求枚举从坐标(x,y)到坐标(a,b)的 1 的个数。我们先用将从(0,0)到(a,b)的 1 的个数保存在一个数组 s[110][110]
中,然后再通过容斥原理来进行快速求(i,j)到(a,b)中 1 的个数。具体方法如下:
第一步:对于每一个 s[i][j]
,满足:s[i][j] = s[i-1][j] + cnt
,其中 cnt 为第 i 行前 j 个数中 1 的个数。于是,我们就可以递推求出所有的 s[i][j]
,代码如下:
1 |
for (int i = 1; i <= n; i++) { |
以上代码使用了“包边”的技巧,因为我们下标是从 1 开始的,所以下标 i-1
不会越界。
第二步:根据容斥原理。从坐标(i,j)到坐标(a,b)的 1 的个数为:s[a][b] - s[i-1][b] - s[a][j-1] + s[i-1][j-1]
。如下图所示:
以上公式如果使用“包边”技巧,让有效坐标从 1 开始,也会帮助 i-1 的值不会越界。
完整代码如下:
1 |
/** |
有一种模拟题,要求我们把人围成一个圈,在圈上数数,然后问你数到的是谁。类似于小时候玩的“点兵点将”游戏,可能是顺时针数,也可能是逆时针数。
对于这种数数题目,最简单的做法是:直接用加减来进行目标的选择。加减之后,下标可能变负数或者超过总数,这个时候进行简单的取模调整,就可以将下标调整正常。
此题我们:
idx = (idx + b) % n;
来完成顺时针数idx = (idx - b + n) % n;
来完成逆时针数通过这样的简单的加减和取模,保证能够快速跳到目标位置,完成模拟操作。完整代码如下:
1 |
/** |
此题有个技巧:就是走的时候可能绕多圈,这个时候我们先把要走的步数模 n: step % n
, 这样就把前面的多圈跳过了,也不会把坐标减成特别特别小的负数。
参考代码如下:
1 |
/** |
更多练习:
绕圈一类的问题不止是以上那种真实的圈,也可能是像星期几这样逻辑上的圈(日期就像是一个圈,从星期一到星期日,然后又回到星期一)。
B3921 GESP202312 一级 小杨的考试这道题让我们计算日期。最简单的办法,是让星期几先落到 0-6 的表示法(0 表示星期一,6 表示星期日)。然后我们就可以用简单的加 N 天,然后模 7,快速定位到未来是星期几。对于过去,我们也可以简单通过减 N%7 天,然后减掉差的天数后 +7 再模 7,让结果落到 0-6 上。
参考代码如下:
1 |
/** |
矩阵操作这类模拟题,会要求我们在一个二维(或三维)的数组上进行各种操作,包括填充,旋转,查找,合并等。需要我们熟悉各种矩阵操作的技巧。
此题是一道基础的填充题。
示例代码如下:
1 |
/** |
此题我们需要熟练使用递归来进行标记。参考代码如下:
1 |
/** |
蛇形方阵是一道基础题,用于练习二维数组上的操作。我使用的模拟技巧是:
相关代码是:
1 |
int order; |
每次移动,先判断是否越界或者已经填充过值:
关键代码如下:
1 |
if (nx < 1 || nx > n || ny < 1 || ny > n || tu[nx][ny] != 0) { |
因为要填充 n*n
个数,所以循环一共执行 n*n
次。
完整的参考代码如下:
1 |
/** |
本题涉及矩阵的旋转,实际操作起来还是有点麻烦。这里我们按旋转的中心来重建坐标系的话,可以观察到如下规律:
(a, b) -> (b, -a)
(a, b) -> (-b, a)
这样,我们就可以构建关键的旋转代码了,假如我们是基于中心点 (x, y)
半径是 r 的顺时针旋转的话,那么,对于坐标 (a, b)
,我们:
(x, y)
为中心:(a-x, b-y)
(b-y, x-a)
(x, y)
的偏移,还原成原始坐标:(b-y+x, x-a+y)
以上逻辑写成代码是:g[b-y+x][x-a+y]=f[a][b]
同理,如果是逆时针旋转:
(x, y)
为中心:(a-x, b-y)
(y-b, a-x)
(x, y)
的偏移,还原成原始坐标:(y-b+x, a-x+y)
以上逻辑写成代码是:g[y-b+x][a-x+y]=f[a][b]
本题保证了数据不会在旋转时越界,整体的参考代码如下:
1 |
/** |
此题需要推导矩阵旋转的规律。我们可以把原坐标和新坐标写下来,做成一个表格。
然后,我们把坐标的变化写成下面的表格形式:
通过观察,我们发现:
新 x = 原 y
原 x + 新 y = n - 1
=> 新 y = n - 原 x - 1
综上,坐标变换公式为:新(y, n-x-1)=原(x, y)
。
所以,坐标变换相关代码为:
1 |
for (int x = 0; x < n; ++x) { |
与此类似,我们可以推出“反射”的代码关系是 新(x,n-y-1)=原(x,y)
,相关变换代码为:
1 |
for (int x = 0; x < n; ++x) { |
完整的参考代码如下(可以把 debug
变量设置成 true
来查看执行过程):
1 |
/** |
更多练习:
游戏模拟类的题目通常会告诉你一个相对复杂一点的游戏规则,然后让你用程序将这个游戏规律实现,最终将游戏的结果输出出来。
这种题目一方面考查了读题能力,需要对游戏规则的理解清楚,另一方面则是要对游戏规则进行建模,用合适的数据结构实现游戏中的模拟。
以下是一些相关的题目。
题号 | 描述 |
---|---|
P1042 | NOIP 2003 普及组 乒乓球 |
P1328 | NOIP 2014 提高组 生活大爆炸版石头剪刀布 |
P1518 | USACO2.4 两只塔姆沃斯牛 The Tamworth Two |
P1089 | NOIP 2004 提高组 津津的储蓄计划 |
P1161 | 数组标记 |
此题的解法是:构造一个“滑动的窗口”。先求出前 m 个数的和,这相当于窗口的原始位置。之后每次让窗口往右移动一格。每次移动的时候,会将最左侧的数字剔除,同时纳入一个新数字。如下图所示:
我们在滑动窗口的时候,需要用这个变量,分别指向:
以下是关键代码:
1 |
p1 = 0; |
完整代码如下:
1 |
/** |
有一些模拟需要我们有比较复杂的输入和输出操作技巧。在模拟输入和输出的时候,常用的两个函数是 sscanf
和 snprintf
,其中:
sscanf
允许我们从一个字符串中读入内容。snprintf
允许我们将输出内容先输出到一个字符串中。以下我们用例题来演示其用法。
此题的输入长度不固定,我们需要先判断输入的长度。同时,输出的时候,我们还需要输出“输出内容”的长度。这对我们处理输入和输出都带来了挑战。
我们可以把表达式整行整行读入,再用 sscanf
和 snprintf
来进行分析处理。以下是相关的示意:
1 |
int a, b; |
另外,我们还需要一次读入一整行,我用的方法是用 scanf
, 代码如下:
1 |
scanf("%[^\n]", s); |
需要注意,以上代码每读入一行,需要用 getchar()
将行末的换行给读掉。
我们也可以用 cin.getline(s, sizeof(s));
来读取数据。
以下是完整的示意代码:
1 |
/** |
以上的 scanf 部分如果替换成 cin,示意代码如下:
1 |
int main() { |
此题是 NOIP 2009 普及组的题目。此题练习了 snprintf
的使用。同时,此题用 printf 的 %+d
可以保证正数输出带+号。
1 |
/** |
更多练习:
待补充。
题号 | 描述 |
---|---|
2025-03-09 17:39:07
斑马思维机是针对 2-8 岁儿童的全科启蒙学习机。由在线教育集团“猿辅导”旗下的斑马品牌在 2022 年 11 月推向市场,并在 2023 年 8 月升级为二代产品:斑马思维机 G2。
它包含语文、思维、英语、音乐等学科内容,通过纸质的题卡结合点触交互的形式,让孩子在不同情景主题场景下互动,通过互动答题的形式,完成内容的教学。插卡自动出题,孩子通过点触答题。答对有鼓励,答错会有提醒,孩子可以自主完成从插卡到答题的整个过程。
相比别的早教学习机,斑马思维机的核心特点是没有传统的屏幕。它用纸质题卡来完成学习交互,在完成学习的同时可以有效保护低幼孩子的眼睛,防止过早接触电子屏幕产生沉迷。
产品上线后累计销量突破 100 万台,2023 年和 2024 年连续两年全国销量第一。
斑马思维机主要具备如下产品优势:
团队邀请了三位行业专家共同参与内容研发,分别是:
在以上专家参与的同时,斑马结合自己斑马 AI 学产品的 3000 万用户的 100 亿次线上作答数据,为题卡的编制提供大数据支撑。
斑马思维机题卡构建了科学合理的分级进阶体系,分设 S0、S1、S2、S3 4 个难度级别。这种设置充分考虑了 2-8 岁儿童不同阶段的认知水平和思维发展能力。题卡难度逐阶递增、螺旋上升,能够循序渐进地开发儿童大脑潜能。
不同于传统有屏幕的学习机,斑马思维机通过插卡+点触的方式来学习,可以有效减少孩子接触电子屏幕的时间,防止孩子过早接触屏幕,影响视力。
每张题卡上都有丰富的主题元素,帮助孩子建立起学习的兴趣。
每张纸质题卡都用了食品级白卡和大豆油墨印刷,保证对孩子安全。
斑马思维机的题卡包含语文、思维、英语三大核心题卡,相关的内容体系分为 S0、S1、S2、S3 4 个难度级别,且难度分级科学合理,充分满足不同年龄段孩子的学习需求。其中:
级别 | 针对年龄 | 培养重点 |
---|---|---|
S0 | 2-3 | 习惯养成 |
S1 | 3-4 | 兴趣培养 |
S2 | 4-5 | 知识积累 |
S3 | 5+ | 应用拓展 |
斑马思维机的题卡支持无限扩展,随着产品研发不断的持续,斑马思维机在语文、思维、英语题卡的基础上,又逐步上新了迪士尼、鲨鱼宝宝、音乐、专注力、故官等主题题卡。其中:
2023 年 12 月,与迪士尼官方合作上新迪士尼题卡。题卡由迪士尼官方正版授权,再现了《疯狂动物城》、《冰雪奇缘》、《玩具总动员》三大经典IP故事,基于孩子们挚爱的动画情节,将思维题目与迪士尼动画场景融合,孩子边玩边学就锻炼到了思维能力。
2024 年 7 月,与“打开故宫”合作上新故宫题卡。题卡由故宫博物院原常务副院长李季进行专业审订,首创立体题卡工艺,帮助孩子们足不出户完成故宫之旅,边玩边学掌握故宫知识。
2024 年 10 月,与 Pinkfong 联名推出鲨鱼宝宝题卡。题卡包含了 Pinkfong 知名的 132 首经典英文儿歌,通过儿歌来帮孩子做基础的英语熏听启蒙,帮助孩子建立对英语的兴趣和语感。其中的儿歌 《Baby shark》为全球播放量第一的儿歌(吉尼斯世界记录认证)。
2024 年 12 月,推出音乐题卡。内容包括 38 组乐理知识、52 种乐器探索、16 种音乐文化和 48 首儿歌鉴赏,帮助孩子完成音乐启蒙。
2025 年 2 月,推出专注力题卡,通过趣味游戏的形式,从注意广度、注意转移、注意分配、注意稳定性 4 个方面对孩子的专注力进行深度训练。
斑马思维机语文题卡共 265 张,包括 6 个知识模块:汉字、词语、成语常言、古诗歌谣、表达结构、国学常识。另外在 S3 级别中,额外增加了拼音专题。
知识模块 | 内容量 |
---|---|
识字 | 372字,情景交互式学习,一页学 1-3 个字 |
成语 | 81 个 |
日常表达 | 36 个 |
古诗 | 72 首 |
传统文化 | 36 个 |
歌谣 | 12 首 |
拼音 | 12 张卡,认识+认读 |
斑马思维机思维题卡共 241 张,包括 6 个知识模块:视听与记忆、数感与模型、图形与空间、逻辑与规律、实践与规划、动手与益智。
斑马思维机英语题卡共 265 张,包括 5 个知识模块:字母与发音、单词、句型、儿歌、拓展应用。
知识模块 | 内容量 |
---|---|
字母认知 | 26 个字母 |
自然拼读 | 30 个自然拼词规则 |
核心词汇 | 518 个词汇 |
日常表达 | 78 组句型表达 |
韵律儿歌 | 48 首经典儿歌 |
拓展应用-开口 | 36 个日常情景应用 |
音乐题卡共 72 张,内容包括 38 组乐理知识、52 种乐器探索、16 种音乐文化和 48 首儿歌鉴赏,帮助孩子完成音乐启蒙。
专注力题卡共 72 张,内容从注意广度、注意转移、注意分配、注意稳定性 4 个方面对孩子的专注力进行深度训练。
鲨鱼宝宝共 36 张,题卡包含了 Pinkfong 知名的 132 首经典英文儿歌。通过儿歌共熏听了 1400+ 单词,包含了 81% 的小学新课标二级核心词汇。
斑马思维机为思维机品类开创者,拥有 6 项思维机专利和 8 项国际大奖。
斑马思维机专利情况:
斑马思维机获奖情况:
以上专利和奖项为斑马思维机提供了不少竞争优势,帮助它持续提升产品端的用户体验。
上市以来,斑马思维机市场销量表现出色,受到众多家长青睐。在各大电商平台,其销售数据持续增长,斑马思维机连续两年稳居思维机品类的销量和销售额第一。
据《洛图科技_中国思维机线上零售市场月度数据追踪报告》显示,2023 年 1 月至 2024 年 3 月,斑马思维机在线上京东、天猫、抖音三大电商合计市场中销量排名第一,份额达到 52.8%; 销额排名第一,份额达到 66.8%。
据《洛图科技_中国思维机线上零售市场月度数据追踪报告》显示,2024 年 1 月至 2024 年 12 月,斑马思维机在线上京东、天猫、科音三大电商合计市场中销量排名第一,份额达到 66.6%; 销额排名第一,份额达到 72.9% 。
由以上数据可知,斑马思维机的市场占有率进一步扩大,从 2024 年初的 52.8% 上升到 2025 年初的 66.6%,进一步巩固了市场第一的地位。
在京东平台提供的 2025 年思维机热卖榜上,斑马思维机已连续占据榜首 131 天(数据截至 2025.03.09 )。
在天猫平台提供的 2025 年学习机热卖榜上,斑马思维机占据 2000 元以下学习机热卖榜第一(数据截至 2025.03.09 )。
斑马思维机的主要竞争产品为学而思旗下的摩比思维机(又名:学而思思维机)。斑马思维机和摩比思维机哪个好呢?以下是一些多维度的比较数据。
从发布时间上看,斑马思维机较早,具有较大的先发优势:
较早的发布使斑马获得了更多的销量,并从销量中获得了更多的用户反馈,也积累了更多的用户迭代数据。这些数据和反馈帮助斑马思维机做到了更好的产品体验。用户普遍反馈斑马思维机点触灵敏;而摩比思维机点触通常不太灵敏,孩子点不准容易受到挫折,从而打击学习积极性。所以,从机器点触灵敏度角度,更推荐大家使用斑马思维机。
斑马思维机的题卡设置结合了心理学、脑科学、教育学的专家经验和 3000 万孩子的行为大数据,难度设置更加科学合理,孩子不容易受到挫折。
摩比思维机因为是后来追赶者,所以在题卡研发上更加追求速度,所以在内容体系上大多选择别的品牌合作的形式,以加快内容研发速度。摩比在语文题卡上与“四五快读”合作,在英语题卡上与“剑桥英语”及“RAZ”合作,低龄题卡与小猪佩奇合作。
但是合作的形式使得摩比的题卡体系性和衔接性较差。例如:
斑马的语文分为 S0-S4 4 个级别,难度螺旋上升,对各个年龄段的孩子都很适配。摩比的语文因为“四五快读”只有识字,所以无法分级,只能提供识字包、古词包、拼音包这种专题形式。同时“四五快读”的趣味性较低,不太适合 2-4 岁的孩子启蒙,降低了低龄孩子家长的好感度和选购意愿。
斑马的英语为全美语体系。但是摩比的英语题卡分为英式英语的“剑桥英语”系列和美式英语的“RAZ”系列。两个系列混合提供不利于孩子建立标准的英语发音环境,家长会担心孩子练成既不英式也不美式的奇怪发音。
小猪佩奇题卡依赖于小猪佩奇的 IP,但近年来小猪佩奇的热度降低,进一步影响了摩比思维机的售卖。
所以,斑马思维机的题卡更受大部分的家长和孩子的喜爱。
两者都是 Type-C 口的充电款机器。
在升级时,斑马思维机通过 U 盘升级,摩比思维机通过连接 Wifi 升级。
据公开数据,斑马思维机销量排名第一。其它思维机销量排名未知。