当前位置: 首页 > news >正文

备战蓝桥杯国赛【day2】

一、数的计算:递归背后的"分形"思维

题目回顾

给定自然数nnn,可以在其左侧不断添加不超过前一个数一半的数字,问能生成多少个数。

初看:简单的递归

deff(n):ifn==1:return1ans=1# 不作任何处理,算一个foriinrange(1,n//2+1):ans+=f(i)returnans

深度思考:这其实是"记忆化搜索"的裸题

这道题的本质是什么?每一个数nnn的生成方案,完全依赖于所有小于等于n/2n/2n/2的数的方案之和。这形成了一棵天然的递归树

f(6) = 1 + f(1) + f(2) + f(3) = 1 + 1 + (1+f(1)) + (1+f(1)) = 6

但等等——如果n≤1000n \leq 1000n1000,纯递归会不会超时?

答案是:不会。因为递归深度最多log⁡2n\log_2 nlog2n,且每个f(i)f(i)f(i)被重复计算的次数有限。但如果nnn扩大到10510^5105呢?这就引出了动态规划的思想:

dp=[0]*(n+1)dp[1]=1foriinrange(2,n+1):dp[i]=1+sum(dp[1:i//2+1])

更进一步,利用前缀和优化,可以将O(n2)O(n^2)O(n2)降到O(n)O(n)O(n)

dp[1]=prefix[1]=1foriinrange(2,n+1):dp[i]=1+prefix[i//2]prefix[i]=prefix[i-1]+dp[i]

💡感悟:递归是"自顶向下"的诗意,DP是"自底向上"的务实。好的算法工程师,能在两者之间自由穿梭。


二、时间加法:不要过度工程化

题目

给定aaabbb分,求ttt分钟后的时间。

我的解法:利用 Python 的datetime

fromdatetimeimportdatetime,timedelta a=int(input())b=int(input())t=int(input())time1=datetime(2000,1,1,a,b)delta=timedelta(minutes=t)time1+=deltaprint(time1.hour)print(time1.minute)

反思:这是"优雅"还是"过度设计"?

datetime确实简洁,但它背后创建了整个日期对象,调用了 C 扩展,对于这么简单的问题是否杀鸡用牛刀

更底层的思考:

# 纯数学解法total=a*60+b+tprint(total//60%24)print(total%60)
方案时间复杂度空间复杂度可读性适用场景
datetimeO(1)O(1)O(1)较高极高复杂日期计算
纯数学O(1)O(1)O(1)O(1)O(1)O(1)简单时间运算

💡感悟:工程中没有绝对的"最好",只有"最合适"。datetime胜在语义清晰,数学法胜在零依赖。面试时,先写数学法展示基本功,再提datetime展示工程意识——双保险


三、人物相关性分析:双指针的华尔兹

题目

统计文本中AliceBob作为独立单词出现,且相距不超过KKK个字符的次数。

核心难点

  1. 单词边界Bobbi不算Bob,需要\b词边界
  2. 字符距离:不是单词距离,是字符位置距离
  3. 效率:字符串长度可达10610^6106,暴力O(n2)O(n^2)O(n2)会 TLE

我的解法:预处理 + 滑动窗口

importre k=int(input())s=input()# 预处理:找出所有 Alice 和 Bob 的起始位置A=[m.start()forminre.finditer(r'\bAlice\b',s)]# Alice 起始位置B=[m.start()forminre.finditer(r'\bBob\b',s)]# Bob 起始位置count=0left=0right=0lenB=len(B)forainA:# Alice 占据 [a, a+5),Bob 占据 [b, b+3)# 两者距离 = max(起点差) - min(终点差) 的某种形式...# 实际上,题目定义的"之间字符数"需要仔细处理L=a-k-3# Bob 最早可以出现的位置R=a+k+5# Bob 最晚可以出现的位置# 移动左指针:找到第一个 >= L 的 Bobwhileleft<lenBandB[left]<L:left+=1# 移动右指针:找到第一个 > R 的 Bobwhileright<lenBandB[right]<=R:right+=1# [left, right) 内的 Bob 都满足条件count+=right-leftprint(count)

算法剖析:为什么这是O(n)O(n)O(n)

关键在于两个指针都只向右移动

  • left指针:一旦越过某个 Bob,再也不会回头
  • right指针:随着 Alice 位置右移,R增大,right也只会右移

这形成了经典的滑动窗口模式,总时间复杂度O(∣A∣+∣B∣)O(|A| + |B|)O(A+B),即线性。

边界条件的艺术

这里的LR计算需要极其小心:

  • Alice长度为 5,Bob长度为 3
  • 如果 Alice 在 Bob 前面,距离 =B - (A + 5)
  • 如果 Bob 在 Alice 前面,距离 =A - (B + 3)

统一处理:

有效区间 = [A - K - 3, A + K + 5]

💡感悟:双指针算法的精髓在于单调性。当一个问题具有"如果iii满足条件,则i+1i+1i+1也可能满足"的单调特征时,双指针就是你的华尔兹舞伴。


四、最大距离:暴力中的数学直觉

题目

数列中两元素距离定义为∣i−j∣+∣ai−aj∣|i-j| + |a_i - a_j|ij+aiaj,求最大值。

数据范围

n≤1000n \leq 1000n1000,允许O(n2)O(n^2)O(n2)暴力。

n=int(input())ls=list(map(int,input().split()))num=-1foriinrange(n):forjinrange(i+1,n):cur=j-i+abs(ls[j]-ls[i])num=max(num,cur)print(num)

但如果n≤105n \leq 10^5n105呢?

绝对值展开后:
∣i−j∣+∣ai−aj∣=max⁡{(i+ai)−(j+aj)(i−ai)−(j−aj)(j+aj)−(i+ai)(j−aj)−(i−ai)|i-j| + |a_i - a_j| = \max\begin{cases} (i + a_i) - (j + a_j) \\ (i - a_i) - (j - a_j) \\ (j + a_j) - (i + a_i) \\ (j - a_j) - (i - a_i) \end{cases}ij+aiaj=max(i+ai)(j+aj)(iai)(jaj)(j+aj)(i+ai)(jaj)(iai)

即:
max⁡(∣(i+ai)−(j+aj)∣,∣(i−ai)−(j−aj)∣)\max(|(i+a_i) - (j+a_j)|, |(i-a_i) - (j-a_j)|)max((i+ai)(j+aj),(iai)(jaj))

所以只需维护(i+ai)(i+a_i)(i+ai)(i−ai)(i-a_i)(iai)的最大最小值,O(n)O(n)O(n)搞定

# 进阶版 O(n) 解法max1=max2=-float('inf')min1=min2=float('inf')fori,xinenumerate(ls):max1=max(max1,i+x)min1=min(min1,i+x)max2=max(max2,i-x)min2=min(min2,i-x)print(max(max1-min1,max2-min2))

💡感悟:绝对值问题,第一反应永远是去绝对值分类讨论。这不仅是技巧,更是一种代数直觉——把几何问题转化为线性问题。


五、进制转换:计算机世界的"翻译官"

题目

实现任意进制(2-16)之间的转换。

核心代码

int_to_char="0123456789ABCDEF"char_to_int={ch:ifori,chinenumerate(int_to_char)}deftrans(s,n,m):# Step 1: N进制 -> 十进制num=0forchins:num=num*n+char_to_int[ch]# Step 2: 十进制 -> M进制ifnum==0:return"0"ans=""whilenum!=0:ans+=int_to_char[num%m]num//=mreturnans[::-1]

进制转换的数学本质

任意进制转十进制
(2022)9=2×93+0×92+2×91+2×90=1472(2022)_9 = 2 \times 9^3 + 0 \times 9^2 + 2 \times 9^1 + 2 \times 9^0 = 1472(2022)9=2×93+0×92+2×91+2×90=1472

代码中的num = num * n + char_to_int[ch]正是霍纳法则(Horner’s Method),将O(n)O(n)O(n)次乘法优化到最优。

十进制转任意进制
本质是不断取模,相当于:
x=dk⋅mk+dk−1⋅mk−1+⋯+d0x = d_k \cdot m^k + d_{k-1} \cdot m^{k-1} + \cdots + d_0x=dkmk+dk1mk1++d0

每次num % m得到最低位d0d_0d0,然后num //= m去掉最低位。

💡感悟:进制转换教会我们——所有进制都是十进制的"投影"。十进制是人类的直觉,二进制是计算机的母语,而算法是它们之间的翻译官。


六、今日心法总结

┌─────────────────────────────────────────┐ │ 1. 递归 → 找重叠子问题 → 考虑记忆化/DP │ │ 2. 字符串匹配 → 预处理 + 双指针/滑动窗口 │ │ 3. 绝对值最值 → 拆四种情况 → 维护极值 │ │ 4. 进制转换 → 霍纳法则 + 取模迭代 │ │ 5. 工程思维 → 没有最好,只有最合适 │ └─────────────────────────────────────────┘

写在最后

刷题不是为了背诵模板,而是为了训练思维的模式识别

当你看到"左边添加不超过一半"时,能否想到递归树?当你看到"两个元素距离限制"时,能否想到滑动窗口?当你看到"绝对值求最值"时,能否想到分类讨论?

这些直觉,才是算法竞赛给予我们最宝贵的财富。

“代码会过时,思维永流传。”

如果你也在刷题路上,欢迎留言交流。算法的世界,一个人走很快,一群人走很远。🚀

http://www.jsqmd.com/news/716546/

相关文章:

  • 手把手教你:基于Intel Agilex 5 E系列FPGA搭建一个边缘AI推理原型(含资源评估)
  • 2026年现阶段武汉休学辍学干预机构深度解析:为何纽特心理成为专业之选? - 2026年企业推荐榜
  • Stable Diffusion加速神器:用DDIM采样算法,让你的AI绘画速度提升10倍(附PyTorch代码)
  • 别再瞎调RAG了!用Ragas框架给你的AI应用做个‘体检’,实测效果提升30%
  • BackupPC数据恢复实战:误删服务器/demo目录后,我是如何用3种恢复方式找回文件的
  • 哪家25-30万家用SUV车型专业?2026年4月推荐评测口碑对比五款产品顶尖亲子出行舒适性差 - 品牌推荐
  • 5步掌握专业缠论分析:ChanlunX通达信插件终极指南
  • 【飞机】飞机的固有频率和模态形状Matlab仿真
  • 如何卸载并重装Oracle Grid_Deinstall脚本与ASM磁盘清理
  • 别只刷题了!用2023年Python省赛真题,手把手教你搭建自己的‘错题本’与复盘系统
  • 直线电机电磁减振系统状态监测【附代码】
  • 告别云干扰!用GEE官方云概率数据集高效处理Sentinel-2影像(附完整代码与避坑指南)
  • Go语言for循环如何写_Go语言for循环语法教程【经典】.txt
  • 3分钟让Windows 11焕然一新:Win11Debloat小白也能懂的终极优化指南
  • 从红蓝对抗视角复盘:OA系统漏洞利用工具V2.0在实战演练中的攻防价值
  • 别再乱装Python全家桶了!手把手教你用Anaconda+Pycharm搞定PyTorch环境(含CUDA配置避坑指南)
  • 2026年Q2安徽甲醇燃料油企业口碑榜揭晓:金立然新能源科技为何脱颖而出? - 2026年企业推荐榜
  • 别再手动合并Excel了!用EasyExcel的CustomMergeStrategy,5分钟搞定报表美化
  • SVPWM七段式Verilog实现避坑指南:死区时间与电压量化那些事儿
  • 2026年北京少儿嘻哈舞培训指南:聚焦舞台实践,这家机构值得关注 - 2026年企业推荐榜
  • 别再只会用top看CPU了!手把手教你用stress-ng在Linux上模拟真实业务压力
  • 2026年现阶段住宅装修设计市场:如何选择靠谱服务商并获取联系方式? - 2026年企业推荐榜
  • 【优化位置】基于粒子群算法的配电系统中电容的最佳位置(降低损耗和电压改善)附Matlab代码
  • 从SSD到CXL:聊聊那些让十亿向量搜索跑得更快的‘近’存储黑科技
  • 金融与游戏App安全加固怎么做?2026年行业定制化方案深度解析
  • TVA在PCB线路板制造与检测中的创新应用(11)
  • Beyond Compare 5密钥生成完全指南:3种方法解决软件授权问题
  • RedHat 9 新手避坑:手把手教你配置阿里云yum源,告别下载龟速
  • 13本大模型入门必看书籍:从零基础小白到精通的完整学习路线
  • 思源黑体TTF:免费多语言字体构建完整指南