☰
成为合作伙伴
CP 每周编程挑战
CCC 2026 J4 - Snail Path 解题与分析
逐步模拟蜗牛移动,用 visited set 记录已经变黏的格子,并统计每一次重新进入旧格子的次数。
想象蜗牛从一个网格方格开始。这个起始方格已经是它路径的一部分,因为题目说明蜗牛碰到的方格会变黏。在“向东移动 3 格”的例子中,一共有 4 个黏黏的方格,其中包括起始方格。
本题在 CCC DSA 地图里的位置
- Level: Junior J4
- 核心方法:网格模拟、坐标状态、访问记录集合
- 前置知识:循环、while/for 模拟、字符串解析、坐标和集合
- 学习重点:把一条看似完整的移动指令拆成逐格状态更新,并在正确时机检查重复访问。
- 相关应用:网格相邻关系、连通区域搜索、BFS 和隐式图搜索
下一步推荐
- 相关 CP Weekly 真题:CCC 2023 J4/S1 Trianglane(grid adjacency)、CCC 2024 J5 Harvest Waterloo(flood fill)、CCC 2020 J5/S2 Escape Room(implicit graph BFS)
- 相关 Python / C++ 基础:loops and accumulation、while simulation、strings parsing、sets、2D coordinates
- 相关 DSA 专题:CCC Grid Problems: from simulation to graph search(planned)
本题在 CCC 数据结构与算法路线图中的位置
- Level: Junior J4
- 核心方法:网格模拟、坐标状态、访问记录集合
- 前置知识:循环、while/for 模拟、字符串解析、坐标和集合
- 学习重点:把移动指令拆成单步操作,正确更新状态,并在合适的时机检查重复访问。
- 相关应用:网格相邻关系、连通区域搜索、BFS 和隐式图搜索
What to Study Next
- Related CP Weekly problems: CCC 2023 J4/S1 Trianglane for grid adjacency, CCC 2024 J5 Harvest Waterloo for flood fill, CCC 2020 J5/S2 Escape Room for implicit graph BFS.
- 相关 Python/C++ 基础:循环与累加、while 模拟、字符串解析、集合和二维坐标。
- 相关算法路线文章:CCC 网格题——从模拟到图搜索(规划中)。
理解题目
每当蜗牛移动一格,我们都检查它到达的新方格是否已经是黏黏的。
- 如果它走到一个从未碰过的方格,答案不增加。
- 如果它走到一个已经黏黏的方格,说明蜗牛回到了旧方格,因此答案加 1。
所以这道题真正要问的是:蜗牛一步一步移动时,有多少次重新进入了旧方格?
学生经常忽略的重要细节
像S2这样的移动并不表示一次大跳跃。它表示先向南移动 1 格,再向南移动 1 格。
必须一格一格处理移动,因为蜗牛可能在一次较长移动的中途进入已经黏黏的方格。移动格式是一个方向字母后接一个最大为 20 的正整数。
核心 DSA 概念
- 模拟:严格按照题意跟随蜗牛移动,逐步更新位置和路径。
- 哈希集合 / visited set: remember which squares are already slimy using coordinate pairs such as
(x, y). - 网格坐标: use
xfor east/west andyfor north/south. - 逐格处理:把每条指令拆成一格一格的移动,再检查该方格是否已经访问过。
坐标更新
- 北:
y += 1 - 南:
y -= 1 - 东:
x += 1 - 西:
x -= 1
核心思路
从起始方格开始,并把它加入 visited set。对于每条移动指令,都一格一格重复移动。每走一步后,检查新的坐标是否已经在集合中。如果在,就把重复进入次数加 1。然后把该坐标加入集合。
Python 解法
# CCC 2026 J4 - Snail Path
# Read the number of movements
M = int(input())
# Current position of the snail
x = 0
y = 0
# The starting square is already touched, so it is slimy
visited = set()
visited.add((x, y))
# Count how many times the snail enters a square
# that was already slimy
answer = 0
# Direction changes for one step
dx = {
"E": 1,
"W": -1,
"N": 0,
"S": 0
}
dy = {
"E": 0,
"W": 0,
"N": 1,
"S": -1
}
# Process each movement
for _ in range(M):
move = input().strip()
# First character is the direction
direction = move[0]
# The rest of the string is the distance
distance = int(move[1:])
# Move one square at a time
for _ in range(distance):
x += dx[direction]
y += dy[direction]
if (x, y) in visited:
answer += 1
visited.add((x, y))
print(answer)
常见错误
- 把
S20当作一次跳跃:这是错误的。蜗牛会一格一格经过 20 个方格,其中任意一个都可能已经是黏黏的。 - 忘记起始方格:起始方格必须一开始就在
visited,否则回到起点时无法正确计数。 - 统计不同的重复方格,而不是总重入次数:输出的是蜗牛进入黏黏方格的次数,而不是有多少个黏黏方格被重新访问。一个方格可以被进入多次,也应该被计数多次。题目也明确说明,一个黏黏的方格可以被进入多次。
- 使用 list 而不是 set:检查某个坐标是否出现过时,set 会快得多。
有问题或建议?
如果你对本文有疑问,或希望提出改进建议,请给我们发送私密留言。