Advent of Code 2017-2020 高频考点与答题技巧:从读题到落码的实战指南

发布时间:2026/10/29 14:06:50

Advent of Code 2017-2020 高频考点与答题技巧:从读题到落码的实战指南 简介这份资源是面向算法练习者与Python学习者的Advent of Code历年题解合集覆盖2017至2020年全部赛题适合希望借助真实编程挑战打磨算法思维、熟悉Python工程写法的中初级开发者。压缩包共240个文件以152个py解题脚本和83个input输入数据为主另含少量png示意图与gitignore配置整体约989KB按年份与日期组织每日一题对应独立脚本便于逐题检索与对照运行。已有137人学习下载。读者可从中获得完整的赛题参考实现涵盖递归、图遍历、动态规划、矩阵操作、字符串处理、位运算与计算几何等题型也能观察itertools、collections等标准库及numpy、pandas在解题中的实际用法并借鉴文件I/O处理、列表推导式与生成器表达式带来的性能优化思路以及代码组织与调试经验适合作为持续刷题与查漏补缺的实践素材。1. 从一道“看起来会做、写出来就翻车”的题说起Advent of Code 的题面几乎从不直接告诉你考什么。它给你一段故事、一份输入文件、一个看似简单的规则然后在你写出第一版代码之后用第二个测试用例把你打回原形。很多人第一次做 AoC 的感受是读题十分钟写码五分钟调试两小时。这不是你水平不行而是这类题的设计逻辑就是“规则藏在细节里边界藏在输入里”。这份题库覆盖 Advent of Code 2017 到 2020 四个年份的完整题目与解法语言以 Python 为主。它适合两类人一是正在刷 AoC、卡在某一天后半段过不去的二是拿 AoC 当算法与工程能力训练场、想把“读题—建模—实现—验证”这条链路练扎实的。拿分的关键不在你会多少算法而在你能不能把题面里的约束一条不漏地翻译成代码里的判断条件。下面按考点模块拆开讲每章都落到具体题目和答题思路上。2. 高频考点四个年份反复出现的六类题型2.1 网格与方向模拟2017 Day 3、2018 Day 13、2020 Day 11AoC 里出现频率最高的一类题是给你一个二维网格让你按某种规则移动、扩散或迭代。2017 Day 3 的螺旋记忆、2018 Day 13 的小车碰撞、2020 Day 11 的座位收敛本质上是同一套骨架定义坐标、定义邻居、定义状态转移、定义终止条件。这类题最常见的翻车点不是算法难而是方向数组写错、边界判断漏掉、状态更新用了原地修改导致同一轮内互相污染。以 2020 Day 11 为例题目要求“同时更新所有座位”如果你在遍历过程中直接改grid后面座位的判断就会读到本轮已经变过的值结果和正确答案差几个数量级。# 2020 Day 11 座位收敛必须用新网格承接本轮结果 def step(grid): rows, cols len(grid), len(grid[0]) new_grid [row[:] for row in grid] # 关键复制而非引用 for r in range(rows): for c in range(cols): occupied count_adjacent(grid, r, c) # 读旧网格 if grid[r][c] L and occupied 0: new_grid[r][c] # elif grid[r][c] # and occupied 4: new_grid[r][c] L return new_gridcount_adjacent读的是旧grid写入的是new_grid两者分离才能保证“同时更新”。参数上注意邻居方向用八方向元组(-1,-1)到(1,1)排除(0,0)边界用0 nr rows判断不要用 try/except 兜底那样会把逻辑错误吞掉。面试官最想听的是你对“状态快照”的理解。这类题通常这么答先声明“我需要两个网格一个读一个写”再说明终止条件是“新旧网格完全相等”最后补一句“迭代次数上限用 while True 加相等判断不预设轮数”。三句话把建模、实现、终止讲完比背代码有用。2.2 解析与状态机2018 Day 5、2019 Day 12、2020 Day 18第二类高频题是“给你一串符号或一行表达式让你按规则化简或求值”。2018 Day 5 的聚合物反应、2019 Day 12 的月球能量模拟、2020 Day 18 的表达式求值考的都是把规则写成状态机或递归下降的能力。2020 Day 18 是典型的分水岭第一部分和*同优先级从左到右第二部分优先级高于*。很多人第一部分写了个简单循环就过了第二部分直接改运算符优先级表结果括号嵌套一深就错。正确做法是把表达式解析成树或者用两次扫描加栈。# 2020 Day 18 第二部分 优先级高于 * def evaluate(expr): # 先处理所有 把结果替换回表达式再处理 * tokens tokenize(expr) # 用栈处理括号遇到 立即结合 ...这类题的答题思路是先问自己“规则能不能用优先级表描述”能就用调度场或递归下降不能就用显式栈。易错点是括号匹配和多位数字的切分tokenize里要区分12和1 2别用单字符遍历。2.3 图搜索与最短路2019 Day 6、2019 Day 18、2020 Day 202019 年是图论大年。Day 6 的轨道传递、Day 18 的钥匙迷宫、Day 20 的传送门迷宫都是 BFS/DFS 加状态压缩。Day 18 的难点在于状态不只是位置还有“已收集钥匙集合”状态空间是位置 × 2^钥匙数直接 BFS 会爆内存必须用位掩码压缩。# 2019 Day 18状态 (r, c, keys_bitmask) from collections import deque def bfs(grid, start): queue deque([(start[0], start[1], 0, 0)]) # r, c, keys, dist seen {(start[0], start[1], 0)} while queue: r, c, keys, dist queue.popleft() for nr, nc in neighbors(r, c): cell grid[nr][nc] if cell #: continue if cell.isupper() and not (keys (ord(cell) - ord(A)) 1): continue # 门没钥匙跳过 new_keys keys if cell.islower(): new_keys | 1 (ord(cell) - ord(a)) state (nr, nc, new_keys) if state not in seen: seen.add(state) queue.append((nr, nc, new_keys, dist 1))位掩码的位移量用ord(cell) - ord(a)保证每把钥匙占一位。seen必须包含 keys否则同一位置不同钥匙集合会被误判为重复。这类题面试常问“状态怎么设计”标准答法是先列影响后续决策的所有变量再判断哪些可以合并成位掩码最后说“状态数 位置数 × 2^关键物品数超过千万就要考虑双向 BFS 或 A*”。2.4 易错点四类反复失分的题与纠正方式错在哪把“同时更新”写成原地更新。为什么错遍历顺序会让后面的格子读到本轮已改的值结果依赖遍历方向。怎么答对先复制一份旧状态所有读操作走旧状态写操作走新状态循环结束后整体替换。错在哪BFS 的seen只记位置不记附加状态。为什么错同一位置在不同钥匙集合下是不同状态漏记会导致提前剪枝、漏解。怎么答对把状态元组完整放进seen入队和判重使用同一个元组。错在哪递归深度没设上限。为什么错2019 Day 6 的轨道链、2020 Day 7 的袋子嵌套输入深度可能上千Python 默认递归上限 1000 直接RecursionError。怎么答对要么改迭代加显式栈要么sys.setrecursionlimit(10000)但优先选迭代别靠调参续命。错在哪输入解析假设固定格式。为什么错AoC 每年输入格式都有细微差异比如分隔符是,还是,行尾有没有空行。怎么答对先打印前几行确认结构再用split加strip双重清洗别一上来就写死索引。提示这四类错误在 2017 到 2020 的题解里反复出现刷题时每写完一版先拿题目给的示例输入跑一遍示例过了再上正式输入能省掉大半调试时间。3. 真题演练三道典型题从读题到落码3.1 2017 Day 7树的重建与根节点定位题目给一堆“节点权重- 子节点列表”的行要求找根节点并算子树总重。读题时先抓两个信息每行第一个词是节点名括号里是权重-后面是子节点。根节点就是“从没出现在子节点列表里”的那个。# 2017 Day 7解析 找根 def parse(lines): weights {} children {} all_children set() for line in lines: parts line.split( - ) left parts[0] name left.split()[0] weight int(left.split(()[1].rstrip())) weights[name] weight if len(parts) 1: kids [x.strip() for x in parts[1].split(,)] children[name] kids all_children.update(kids) root set(weights) - all_children return weights, children, root.pop()rstrip())去掉右括号set(weights) - all_children一步得到根。第二部分要找“哪个节点的子树权重不平衡”思路是后序遍历算每个节点的子树总重再对每个节点的子节点权重分组找出唯一不同的那个。答题时先说“我需要一次后序求总重再一次前序找异常”面试官就知道你分得清两趟遍历的用途。3.2 2019 Day 14化学反应的拓扑排序与余料管理题目给一组反应式每种产物需要若干原料原料可能又是别的反应的产物问造 1 个燃料最少需要多少矿石。这是带余料的拓扑排序先按依赖关系排序从需求倒推每步算需要多少批反应余料存起来供后续使用。# 2019 Day 14倒推需求余料用字典记录 def solve(reactions, fuel1): need {FUEL: fuel} surplus {} # 按拓扑序处理这里简化为循环直到没有非 ORE 需求 while any(k ! ORE and v 0 for k, v in need.items()): for product in list(need): if product ORE or need[product] 0: continue qty, inputs reactions[product] times (need[product] surplus.get(product, 0) qty - 1) // qty surplus[product] times * qty - need[product] need[product] 0 for inp, amount in inputs: need[inp] need.get(inp, 0) times * amount return need.get(ORE, 0)times用向上取整(a b - 1) // bsurplus记录多生产的量。易错点是处理顺序如果先处理下游再处理上游余料会算错所以要么显式拓扑排序要么像上面这样循环到收敛。面试常追问“为什么不能贪心一次过”答“因为余料会改变后续批次数必须迭代到稳定”。3.3 2020 Day 22双人卡牌游戏的递归与状态判重题目是两个玩家各持一叠牌每轮比大小大的收走两张。第二部分加了“递归子游戏”如果双方剩余牌数都够就开一局子游戏决定本轮胜负。难点在递归终止和防止无限循环。# 2020 Day 22 第二部分递归子游戏 状态判重 def play(p1, p2): seen set() while p1 and p2: state (tuple(p1), tuple(p2)) if state in seen: return 1, p1 # 重复状态玩家 1 胜 seen.add(state) a, b p1.pop(0), p2.pop(0) if len(p1) a and len(p2) b: winner, _ play(p1[:a], p2[:b]) else: winner 1 if a b else 2 if winner 1: p1.extend([a, b]) else: p2.extend([b, a]) return (1, p1) if p1 else (2, p2)seen存的是双方手牌的元组快照一旦重复说明进入循环按规则判玩家 1 胜。递归调用传的是切片副本p1[:a]不能传引用否则子游戏会改到父游戏的牌。这类题的答题模板是先讲“状态是什么”再讲“重复状态怎么判”最后讲“递归边界在哪”三句话覆盖设计意图。4. 答题节奏从读题到提交的四步固定动作4.1 第一步把示例输入手算一遍AoC 的题面几乎都带一个迷你示例和期望输出。别急着写代码先拿纸或注释把示例走一遍确认你理解的规则和题面一致。2018 Day 5 的聚合物反应示例里aA消掉、abBA消成空手算一遍就知道“相邻且大小写相反”是唯一消除条件不会误加“同字母”判断。4.2 第二步先写解析打印结构输入解析错了后面全错。固定动作是写完解析先print前几行和总行数确认字段数、分隔符、空行处理都对。2019 Day 12 的月球坐标是x-1, y0, z2这种格式用正则-?\d提取三个数最稳别用split硬切。4.3 第三步小函数拆分单测示例把“解析”“单步演化”“判终止”“算答案”拆成四个函数每个函数拿示例数据单独跑。2020 Day 11 的step函数可以单独喂一个 3×3 网格看一轮之后是不是期望的形态。拆开的好处是出错时能定位到具体环节不用在两百行里找 bug。4.4 第四步正式输入跑通后回头检查边界正式输入跑出答案先别提交回头检查三件事循环终止条件是不是“状态不再变化”而不是固定轮数累加变量有没有用int溢出Python 不用担心但逻辑上要确认量级递归或迭代的深度有没有上限保护。这套动作走顺了一天两题不是问题。步骤动作检查点读题手算示例规则理解与题面一致解析打印结构字段数、分隔符、空行实现拆小函数每个函数单独过示例验证正式输入 边界复查终止条件、状态判重、深度注意表格里的四步是固定顺序别跳步。跳步的代价通常是“答案对了但不知道为什么对”换一道同类型题又不会了。5. 押题思路下一轮最可能卡住你的三个地方5.1 状态空间爆炸时的剪枝选择2019 Day 18 和 2020 Day 20 都出现过“状态太多跑不动”的情况。押题方向是给你一个带附加状态的搜索题问你怎么压。标准答法是先算状态上界再判断能不能用位掩码合并布尔量最后考虑双向 BFS 或按层剪枝。面试官想听的是“你先估量级再选结构”不是直接背 A*。5.2 递归改迭代的时机2017 Day 7 和 2019 Day 6 的递归深度都可能破千。押题思路是凡是“沿着父子链走到底”的题优先写迭代加显式栈递归只用在深度可控的分治上。答题时补一句“Python 默认递归上限 1000我不靠调参直接改迭代”比说“我设了 setrecursionlimit”更稳。5.3 多阶段规则的优先级切换2020 Day 18 的两部分规则不同2018 Day 5 的第二部分要“删掉某个字母再反应”。押题方向是同一题面下规则切换你怎么组织代码。答法是“把规则抽成参数或策略函数主流程不变只换策略”这样第二部分不用重写解析和遍历。我自己的习惯是每道题提交前强制走一遍“示例—解析—单步—边界”四步哪怕题面再简单也不跳。有一次 2020 Day 11 我图快直接上正式输入跑了十分钟不收敛回头发现是原地更新导致状态震荡白等十分钟。从那以后我每次写网格题都先复制一份旧状态这个动作已经成了肌肉记忆。希望这份按考点拆开的题库能帮你少走几段弯路把时间花在真正卡人的边界条件上。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/29 14:06:50

Advent of Code 2015-2020 六年题库算法考点与答题节奏全解析

简介:面向希望借经典赛题打磨算法与Python工程能力的开发者,这份资源汇集了Advent of Code 2017至2020年全部题目的个人解答,按年份与日期组织成可直接运行的代码仓库,适合作为刷题参考、算法复盘与语言进阶的实战素材。压缩包共2…

2026/10/29 14:01:49

嵌入式非易失存储选型:FRAM、MRAM、EERAM与ReRAM对比

做嵌入式存储选型的人,近几年大概都被同一个场景折磨过:产品要求每秒记录一次运行数据,还要保证掉电瞬间不丢,用传统EEPROM算一算寿命,一天就写穿;换NOR Flash,擦除块大、写入慢,掉电…

2026/10/29 14:01:49

人形机器人技术突破与供应链变革分析

1. 人形机器人行业爆发前夜:从摩根士丹利预测看产业变革2024年的人形机器人行业正站在爆发式增长的前夜。摩根士丹利最新研报预测,到2026年全球人形机器人销量将实现133%的惊人增长,而中国供应链企业正在这场产业变革中扮演关键角色。作为跟踪…

2026/10/29 15:02:10

中小企业AI建站工具的成本优势与技术实践

1. 为什么中小企业开始拥抱AI建站工具上周帮朋友的小型设计工作室搭建官网时,我惊讶地发现从注册域名到上线完整网站只用了47分钟——这个速度在五年前需要专业团队工作一周。如今像Wix ADI、Bookmark等AI建站平台正在颠覆传统建站模式,根据BuiltWith统计…

2026/10/29 15:02:10

AI监控器在制造业的应用与架构设计

1. 项目概述:AI监控器如何重塑制造业竞争格局在金属加工车间里,老师傅们常说要"听声辨位"——通过机床运转的声音判断刀具磨损程度。如今,这套经验法则正在被AI监控器数字化。作为在工业AI领域深耕多年的架构师,我发现制…

2026/10/29 15:02:10

吸收光谱技术实操指南:光路、光源、探测与数据解析全闭环

1. 什么是吸收光谱技术:从实验室台面到产线现场的真实存在吸收光谱技术不是教科书里那个被简化成几条竖线的抽象图示,也不是PPT上一闪而过的“高大上”术语。它是我过去十年在多个项目现场反复调试、校准、推翻重来又重建的日常工具——某高校光学实验室…

2026/10/29 15:02:10

SpringBoot公益餐饮平台开发与智能匹配算法实践

1. 项目背景与核心价值 郑州爱心餐饮联盟平台是一个基于SpringBoot框架开发的公益性质餐饮协同管理系统。这个毕业设计选题的巧妙之处在于,它抓住了当前社会对公益事业数字化转型的迫切需求。随着互联网技术的普及,传统公益餐饮服务面临着信息不对称、资…

2026/10/29 15:02:10

iOS 17+ 免越狱虚拟定位:基于libimobiledevice的合规轨迹模拟方案

简介:本资源是一款面向iOS 17设备用户的免越狱虚拟定位跑步模拟工具,专为需在不实际运动场景下完成健康类App打卡(如Keep、Nike Run Club等)的开发者与进阶用户设计。它通过CLI命令行方式实现路径在线拾取、自定义距离/速度/时间等…

2026/10/29 14:57:08

C语言数据结构入门:从链表到算法的工程实践

简介:本资源是一套面向C语言初学者与算法进阶学习者的数据结构与算法实践代码合集,聚焦线性表、栈、队列、树、图、查找、排序等核心模块的C语言实现,覆盖高校课程教学与工程实践常见需求。压缩包共558个文件,以80个.c源码文件为主…

2026/10/28 14:42:12

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/28 15:28:56

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/28 3:32:29

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/29 0:03:42

学生选课系统DFD图绘制指南:边界划分与分层校验实战

简介:文档以顶层与第一层DFD图为核心,完整刻画学生选课系统的逻辑模型,面向软件工程课程设计、系统分析学习及毕设前期建模人群。顶层图界定系统边界,外部实体包括管理员、教师和学生三类角色;第一层图进一步细化用户登…

2026/10/29 0:03:42

JIRA敏捷落地:Scrum角色权限、Sprint与燃尽图避坑指南

简介:围绕“基于JIRA的敏捷开发项目管理”这一主题,面向产品负责人、Scrum Master及研发测试成员,梳理Scrum角色分工、迭代流程与JIRA工具配置的对应关系,适合初、中级团队导入敏捷管理时参考。压缩包共1个docx文件,大…

2026/10/29 0:03:42

SEMI S8人机工程验收实战:从条款拆解到现场实测的完整指南

简介:面向半导体设备设计、制造与运维工程师及安全合规人员,这份资料聚焦SEMI标准体系下的设备安全规范,重点收录SEMI S8-0308《半导体制造设备人体工程学工程安全指南》。内容围绕设备设计原则、错误与事故预防、人体工程学适配三大主线展开…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑