小U的问号替换问题 | 豆包MarsCode AI刷题

66 阅读3分钟

问题背景

在编程和算法领域,我们经常会遇到一些看似简单但实际上需要巧妙解决方案的问题。今天,我们要探讨的就是这样一个问题:给定一个由数字字符和问号(?)组成的字符串,我们的任务是将所有的问号替换成数字字符,使得替换后的字符串表示的十进制整数成为给定正整数p的倍数。这个问题不仅考验了我们对字符串操作的熟练程度,还涉及到了动态规划和模运算的知识。

问题描述

小C拿到了一个由数字字符和问号(?)组成的字符串,她的目标是将所有的问号替换成数字字符,使得替换后的字符串表示的十进制整数成为正整数p的倍数。由于方案数可能非常大,需要对最终的结果取模 109+7109+7。

代码实现

为了解决这个问题,我们可以使用动态规划的方法。以下是Python语言的实现代码:

def solution(s: str, p: int) -> int:
    MOD = 10**9 + 7
    n = len(s)
    dp = [[0] * p for _ in range(n + 1)]
    
    # 初始化
    dp[0][0] = 1
    
    # 遍历字符串
    for i in range(n):
        for r in range(p):
            if dp[i][r] > 0:
                if s[i] == '?':
                    for digit in range(10):
                        new_r = (r * 10 + digit) % p
                        dp[i + 1][new_r] = (dp[i + 1][new_r] + dp[i][r]) % MOD
                else:
                    digit = int(s[i])
                    new_r = (r * 10 + digit) % p
                    dp[i + 1][new_r] = (dp[i + 1][new_r] + dp[i][r]) % MOD# 最终答案
    return dp[n][0]

if __name__ == '__main__':
    print(solution("??", 1) == 100)
    print(solution("????1", 12) == 0)
    print(solution("1??2", 3) == 34)

代码分析

初始化

我们首先定义了一个模数 MOD,这是为了处理大数问题。然后,我们初始化了一个二维数组 dp,其中 dp[i][j] 表示字符串的前 i 个字符能被 j 整除的方案数。

动态规划逻辑

我们使用两层循环来遍历字符串和可能的余数。对于每个字符,如果它是问号,我们尝试用0到9的数字替换它,并更新 dp 数组。如果字符不是问号,我们直接使用它,并更新 dp 数组。

更新 dp 数组

在更新 dp 数组时,我们使用了取模操作来确保结果不会超出整数范围。

最终结果

最后,我们返回 dp[n][0],它表示整个字符串能被 p 整除的方案数。

难点分析

  • 动态规划状态转移:理解如何根据当前状态更新下一个状态是解决这个问题的关键。
  • 大数处理:由于结果可能非常大,我们需要在每一步都进行取模操作以避免整数溢出。
  • 边界条件处理:在处理字符串的最后一个字符时,我们需要确保它能够正确地影响最终的结果。