一、前言
学完 Python 的基础语法之后,很多人会陷入"语法都会,题目不会写"的状态。其实入门阶段的编程题,套路高度一致:
读输入 → 循环处理每一步 → 用条件判断决定怎么做 → 把过程和数据存起来 → 输出结果。
今天用一个很典型的小题目——坐标移动与路线记录——把上面这条链路完整走一遍。它看起来简单,但把"状态维护""轨迹记录""列表追加""边界判断"这几个入门必考点全考到了。
二、题目描述
初始位置为(x, y) = (0, 0),输入一串只包含大写字母F、B、L、R的字符串(不含空格)。程序从左到右逐个处理,每个字母计为一步。
字母 | 处理规则 |
F | y 加 1,x 不变 |
B | y 减 1,x 不变 |
L | x 减 1,y 不变 |
R | x 加 1,y 不变 |
程序要求:
- 使用
input()读取一串字母,使用循环和条件判断更新坐标;
- 用列表记录起点和每一步结束后的位置,并按顺序输出;
- 输出最终坐标、总步数及是否回到起点(最终 x、y 均为 0 时输出"已回到起点",否则输出"未回到起点")。
输入输出示例:输入FRBL
测试数据(需分别运行,输出完整路线和结果):
输入 | 最终坐标 | 总步数 | 是否回到起点 |
FRBL | (0, 0) | 4 | 是 |
FFRBL | (0, 1) | 5 | 否 |
RRBB | (2, -2) | 4 | 否 |
三、思路分析
这道题的核心其实只有一句话:
循环负责"走",条件负责"往哪走",列表负责"记住走过的路"。
拆成三个要点:
① 状态怎么存?
用一个变量对(x, y)表示当前坐标,初始为(0, 0)。每读一个字母,就根据字母去修改x或y——这就是"状态维护"。
② 一步一步怎么走?
for循环遍历字符串的每一个字符,在循环体里用if/elif/elif/elif判断是哪个字母,然后对坐标做对应加减。
③ 轨迹怎么记?
先用列表存一个起点[(0, 0)],然后每走完一步就把当前坐标append进去。这样列表里天然就是"起点 → 中途 → 终点"的完整路线,顺序完全正确。
④ 结果怎么算?
- 最终坐标 = 循环结束后
(x, y)的值;
- 总步数 = 列表长度 − 1(因为多存了一个起点);
- 是否回到起点 = 判断
x == 0 and y == 0。
四、完整代码
# -*- coding: utf-8 -*- """ 9.30 号任务 · 上午:位置计算与路线记录 题目要求 -------- 初始位置为 (x, y) = (0, 0),输入一串只含大写字母 F / B / L / R 的字符串 (不含空格),程序从左到右逐个处理,每个字母计为一步。 字母 处理规则 ---- ------------------ F y 加 1,x 不变 B y 减 1,x 不变 L x 减 1,y 不变 R x 加 1,y 不变 程序要求 -------- 1. 使用 input() 读取一串字母,使用循环和条件判断更新坐标; 2. 用列表记录起点和每一步结束后的位置,并按顺序输出; 3. 输出最终坐标、总步数及是否回到起点 (最终 x、y 均为 0 输出“已回到起点”,否则输出“未回到起点”)。 """ def step(x, y, command): """根据单个指令字母,返回移动一步后的新坐标 (x, y)。 参数: x, y : 当前坐标 command : 单个指令字符,F / B / L / R 之一 返回: (x, y) : 移动后的新坐标 """ if command == 'F': # 向前:y 加 1 y += 1 elif command == 'B': # 向后:y 减 1 y -= 1 elif command == 'L': # 向左:x 减 1 x -= 1 elif command == 'R': # 向右:x 加 1 x += 1 # 非法字符不改变坐标(保持鲁棒性,不计为一步) return x, y def walk(commands): """处理一整串指令,返回 (路线列表, 最终坐标, 总步数)。 路线列表以起点 (0, 0) 开始,之后每走一步追加一个位置。 """ x, y = 0, 0 route = [(x, y)] # 列表第 1 个元素记录起点 for command in commands: if command not in "FBLR": # 跳过非法字符,不计入步数 continue x, y = step(x, y, command) route.append((x, y)) # 每走一步,记录一次当前位置 steps = len(route) - 1 # 总步数 = 位置个数 - 起点 return route, (x, y), steps def format_route(route): """把路线列表拼成 (0, 0) → (0, 1) → ... 的字符串。""" return " → ".join("({}, {})".format(px, py) for px, py in route) def show_result(commands): """对一组输入完成计算并打印全部结果。""" route, (x, y), steps = walk(commands) back_to_start = (x == 0 and y == 0) print("-" * 46) print("输入:{}".format(commands)) print("路线:{}".format(format_route(route))) print("最终坐标:({}, {})".format(x, y)) print("总步数:{}".format(steps)) print("已回到起点" if back_to_start else "未回到起点") def main(): """基本任务:在运行窗口中输入一串字母,输出路线与结果。""" print("=" * 46) print("上午任务:位置计算与路线记录") print("=" * 46) print("\n【基本任务】请输入一串字母(F/B/L/R),直接回车则只跑测试:") commands = input().strip().upper() if commands: show_result(commands) # 按题目“测试与提交”要求,依次运行三组给定输入 print("\n【测试与提交】三组测试数据:") for case in ["FRBL", "FFRBL", "RRBB"]: show_result(case) if __name__ == "__main__": main()五、运行结果
RBL为例(同时自动跑完三组测试数据)
对照题目给出的测试表,三组结果完全一致✅
六、几个值得注意的细节
6.1 为什么要把起点也放进列表?
如果只在"每步之后"追加,列表长度就等于步数;先放起点之后,长度 = 步数 + 1。
好处是打印路线时可以直接用" → ".join(...)拼出完整的"起点 → 中途 → 终点",逻辑上一目了然。如果不想存起点,也可以后面临时补一个,但那样代码更绕。
6.2 为什么用if/elif而不是四个独立if?
F/B/L/R四个字母是互斥的,一个字符只可能属于其中一种情况。用elif可以在命中后立刻跳过后续判断,效率更高、语义也更准确——"不是 F,才继续看是不是 B"。
6.3 总步数为什么不是len(commands)?
因为代码里对非法字符做了continue跳过处理。如果输入里混入了X、1这类字符,它们不应该算作一步。所以用len(route) - 1来统计,才是真正"走出来的步数",更严谨。
6.4 换一种更短的写法:字典查表
学过字典之后,可以用映射表代替一长串if/elif,代码会清爽很多:
用字典 + 元组把"条件判断"变成了"查表"。以后如果要扩展指令(比如加斜向移动Q/W/E),只要往字典里加一行就行,不用改一堆elif——这就是"数据驱动"的小优势。
6.5input().strip().upper()的三连操作
strip():去掉首尾空格(用户手抖敲的空格、回车);
upper():统一转成大写,这样输入frbl也能正确运行。
对用户宽容一点,程序就健壮一点。这是新手很容易忽略的细节。
七、知识点小结
知识点 | 在本题目中的应用 |
| 读取一行指令串 |
| 输入清洗与大小写归一 |
| 从左到右遍历每个字符 |
| 判断当前字母是 F / B / L / R |
变量状态维护 | 用 |
列表 | 记录起点和每一步的位置 |
元组 | 用 |
| 把路线拼成带箭头的字符串 |
布尔表达式 |
|
函数封装 |
|
7.1 关于"函数拆分"的思路
这道题完全可以塞进一个main()里,但拆成几个小函数更好:
step()—— 只管"一步怎么走",职责单一;
walk()—— 只管"整串怎么走,并记录轨迹";
format_route()—— 只管"怎么把路线显示得好看";
show_result()—— 只管"怎么输出结果"。
一个函数只做一件事,是写出可维护代码的第一步。以后需求变了(比如不同题目要换显示格式),只要改对应那一个函数即可。
7.2 这类题的通用套路
以后遇到类似的"按指令序列改变状态"的题(比如走迷宫、解析命令、简单机器人模拟),都可以套用这套模板:
八、扩展练习
想进一步巩固,可以试试:
- 统计各方向步数:统计
.count('F')、.count('B')等,看看向各方向各走了几步;
- 计算曼哈顿距离:最终坐标到原点的曼哈顿距离 =
abs(x) + abs(y);
- 输出最远点:从路线中找出离原点最远的那一步;
- 支持多组输入:用
while True循环,直到用户输入quit才退出。
九、结语
这道题本身不难,但它把入门阶段最重要的三件事练透了:
- 循环—— 把"重复处理每一个输入"交给
for;
- 条件—— 把"根据情况做不同的事"交给
if/elif/else;
- 数据组织—— 用列表记录轨迹、用元组表示坐标。
一旦你能把题目拆成"状态 + 循环 + 条件 + 数据容器",绝大多数入门编程题都会变得有章可循。
如果这篇文章对你有帮助,欢迎点赞 + 收藏,后续会继续更新更多 Python 入门实战题的解析~
本文为原创内容,代码已在 Python 3.13 环境下实测通过。