题解:P12381 [蓝桥杯 2023 省 Python B] 保险箱

· · 题解

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main() {
    int n;
    string x, y;
    cin >> n >> x >> y;  // 读取输入

    int res = 0;  // 记录总操作次数
    int carry = 0;  // 记录进位/退位的影响

    // 从最低位(最右边)开始处理
    for (int i = n - 1; i >= 0; --i) {
        int a = x[i] - '0' + carry;  // 当前x的数字加上进位/退位
        int b = y[i] - '0';          // 当前y的数字
        carry = 0;  // 重置进位/退位

        if (a == b) {
            continue;  // 数字相同,无需操作
        }

        // 计算直接调整的步数(不考虑进位)
        int direct = abs(b - a);
        // 计算通过进位/退位调整的步数
        int wrap = 10 - direct;  // 例如:a=9, b=0,直接调整需要9步,进位调整需要1步

        // 选择步数更小的方式
        if (direct < wrap) {
            res += direct;
        } else {
            res += wrap;
            // 记录进位/退位的影响(下一位需要调整)
            if (b > a) {
                carry = -1;  // 退位(例如:a=0, b=9,退位后a=9,相当于+9)
            } else {
                carry = 1;   // 进位(例如:a=9, b=0,进位后a=0,相当于-9)
            }
        }
    }

    cout << res << endl;
    return 0;
}

代码注释:

‌输入处理‌:

读取数字位数 n,初始数字 x 和目标数字 y。 ‌初始化‌:res 记录总操作次数,carry 记录进位/退位的影响。 ‌从右到左处理‌:因为进位/退位会影响左边的数字,所以从最低位开始处理。

‌数字比较‌:

如果当前位数字相同(考虑进位后),则跳过。 否则计算两种调整方式的步数:

‌直接调整‌:

直接增加或减少数字到目标值。 ‌进位/退位调整‌:通过进位或退位间接调整(例如:9 -> 0 可以通过 +1 进位实现,步数为 1)。

‌选择最小步数‌:

比较两种方式的步数,选择较小的,并更新 res 和 carry。

‌输出结果‌:

打印最少操作次数。