数字魔法的加一操作| 豆包MarsCode AI刷题

133 阅读5分钟

问题描述

数字魔法师小U发现了一种特殊的数字变换魔法。这个魔法可以对一个数字字符串进行"进位"操作。每次操作规则如下:

  • 对字符串中的每个数字进行加一操作
  • 当某位数字为9时,加一后变成 0,并在前面补 1

例如:

  • "798" 经过一次操作变成 "8109"(7→8, 9→0并向前增加一个1, 8→9)
  • "999" 经过一次操作变成 "101010"

现在给定一个数字字符串 num_str(长度为n)和操作次数 k,请计算经过 k 次操作后得到的最终结果。由于结果可能非常大,请将答案对 1000000007 (10^9 + 7) 取模。

输入

  • 第一行包含两个整数 n 和 k(1 ≤ n ≤ 50, 1 ≤ k ≤ 100)
  • 第二行包含一个长度为n的数字字符串 num_str,仅由数字0-9组成

返回

  • 返回一个整数,表示最终结果对 1000000007 取模后的值

测试样例

样例1:

输入:n = 3 ,k = 1 ,num_str = "798"
返回:8109
解释:798 经过一次操作变成 8109

样例2:

输入:n = 3 ,k = 3 ,num_str = "798"
返回:103221

  • 第一次操作:798 → 8109
  • 第二次操作:8109 → 92110
  • 第三次操作:92110 → 103221

样例3:

输入:n = 4 ,k = 3 ,num_str = "7989"
返回:10322132

代码解析与解答

代码解答

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

const int MOD = 1000000007;

int solution(int n, int k, string num_str) {
    while (k > 0) {
        string next_num = "";
        // 将字符串中的每一位数字加1
        for (char c : num_str) {
            int digit = c - '0'; // 将字符转换为整数
            next_num += to_string(digit + 1); // 加1后转回字符串并拼接
        }
        num_str = next_num; // 更新 num_str
        k--;
    }

    // 将结果字符串转换为整数并取模
    long long result = 0;
    for (char c : num_str) {
        result = (result * 10 + (c - '0')) % MOD;
    }
    return result;
}

int main() {
    // 测试用例
    cout << solution(3, 1, "798") << endl;  // 输出 8109
    cout << solution(3, 3, "798") << endl;  // 输出 103221
    cout << solution(4, 3, "7989") << endl; // 输出 10322132
    return 0;
}

代码结构分析

  1. 常量定义

    const int MOD = 1000000007;
    
    • 由于结果可能很大,我们需要对 109+710^9+7 取模。MOD 是一个常用的大质数,用于防止整数溢出,尤其在涉及高精度计算时。
  2. 主逻辑函数 solution

    • 输入:数字字符串 num_str,长度 n,操作次数 k
    • 输出:经过 k 次数字逐位加 1 操作后的结果,对 109+710^9+7 取模。
  3. 操作实现

    • 逐位加 1

      for (char c : num_str) {
          int digit = c - '0'; // 将字符转换为整数
          next_num += to_string(digit + 1); // 加1后转为字符串
      }
      
      • 遍历字符串,将每个字符转换为整数,执行加 1 操作后,转回字符串并拼接到结果中。
    • 更新结果字符串

      num_str = next_num;
      
      • 每次操作的结果更新为新的字符串,供下一轮使用。
  4. 结果取模

    • 将处理完成的字符串逐位转换为整数,同时逐步取模:

      long long result = 0;
      for (char c : num_str) {
          result = (result * 10 + (c - '0')) % MOD;
      }
      
      • 这种方法避免了直接转换超大整数导致溢出问题。
  5. 主函数测试

    • 调用 solution 函数,传入测试用例,并输出结果。

代码的完整性与扩展性

  1. 处理多轮操作

    • 循环内的字符串逐位操作可扩展到任意次数,满足题目约束 k≤100k \leq 100。
  2. 大数处理能力

    • 字符串操作结合逐步取模的方法,能有效处理长达 50 位的数字。

运行示例

示例 1:

输入:solution(3, 1, "798")
输出:8109
过程

  • 第 1 次操作:7988109
  • 最终结果对 109+710^9+7 取模:8109 % 1000000007 = 8109
示例 2:

输入:solution(3, 3, "798")
输出:103221
过程

  • 第 1 次操作:7988109
  • 第 2 次操作:810992110
  • 第 3 次操作:92110103221
  • 最终结果对 109+710^9+7 取模:103221 % 1000000007 = 103221
示例 3:

输入:solution(4, 3, "7989")
输出:10322132
过程

  • 第 1 次操作:7989810910
  • 第 2 次操作:8109109211011
  • 第 3 次操作:921101110322132
  • 最终结果对 109+710^9+7 取模:10322132 % 1000000007 = 10322132

总结与扩展

总结

  1. 功能清晰

    • 实现了逐位加 1 的数字字符串操作,符合问题要求。
  2. 关键技术点

    • 字符串处理:将字符串当作大数存储,并模拟数字加法。
    • 高效取模:通过逐位累积的方法避免直接处理超大整数。
  3. 复杂度分析

    • 时间复杂度:每次操作 O(n)O(n),共 kk 次,总复杂度为 O(kn)O(kn),其中 nn 是字符串长度。
    • 空间复杂度:存储结果字符串和中间变量,复杂度为 O(n)O(n)。

生活中的应用场景

  1. 大整数计算

    • 在密码学中,大整数的处理(如 RSA 加密)常常需要字符串模拟加法和取模操作。
  2. 循环计数

    • 模拟计数器的进位(如机械里程表或电子设备计数器),逻辑类似本题逐位加法。
  3. 金融与物流

    • 处理长数字(如订单号、银行账户)的逐步操作,可用于订单系统、编号生成等场景。