1. 问题背景与核心挑战
这道UVa 12261题目模拟了一个经典的游戏场景:玩家在获得高分后需要用摇杆输入自己的名字。系统初始显示一个全'A'的字符串,我们需要计算将初始字符串转换为目标名字所需的最少摇杆移动次数。
1.1 游戏摇杆的操作特性
摇杆操作分为两个维度:
- 垂直方向:改变当前选中字母(向前/向后)
- 水平方向:移动光标位置(向左/向右)
两个维度都是循环的:
- 字母表循环:'Z'之后是'A','A'之前是'Z'
- 位置循环:第一个字母左边是最后一个字母,最后一个字母右边是第一个字母
1.2 问题分解
我们需要将总移动次数分解为:
- 垂直移动次数:将所有字母从'A'修改为目标字母
- 水平移动次数:光标访问所有需要修改的位置
关键观察:只有当目标字母不是'A'时才需要访问该位置
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 垂直移动次数的计算
2.1 字母变换的基本原理
对于每个字母c,从'A'到c的最小移动步数为:
code复制min(c - 'A', 26 - (c - 'A'))
这是因为字母表是环形的,我们可以选择正向或反向移动。
2.2 实现细节
cpp复制int verticalMoves = 0;
for (char c : name) {
int diff = c - 'A';
verticalMoves += min(diff, 26 - diff);
}
例如:
- 'B':min(1, 25) = 1
- 'Z':min(25, 1) = 1
- 'M':min(12, 14) = 12
- 'N':min(13, 13) = 13
3. 水平移动次数的优化
3.1 基本策略分析
我们需要找到访问所有非'A'位置的最小水平移动次数。考虑四种基本策略:
| 策略 | 描述 | 移动次数公式 |
|---|---|---|
| 一直向右 | 从位置0向右走到最后一个非'A' | lastNonA |
| 一直向左 | 从位置0向左走到第一个非'A' | n - firstNonA |
| 先右后左 | 向右到i,然后向左到j | i*2 + (n-j) |
| 先左后右 | 向左到i,然后向右到j | ( |
