简单记录一下《数字魔法的加一操作》这道题解题思路。
题面如下:
问题描述
数字魔法师小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
- 第一次操作:7989 → 810910
- 第二次操作:810910 → 9211021
- 第三次操作:92110 → 10322132
解题思路
这个问题难点在于9进位操作变成10,在下一次操作中优惠拆分成1和0分别执行进位操作,而不是作为一个总体,所以我们可以考虑通过将数字字符串转换为列表,并在列表上进行操作,实现了对数字字符串的 k 次进位操作。每次操作后,将列表转换回字符串,再转换回列表,以便进行下一次操作。最终,将结果转换为整数并取模后返回。
具体过程如下:
1、首先完成初始化:定义了一个常量 MOD,用于对结果取模。将输入的数字字符串 num_str 转换为列表 num_list,便于后续操作。
2、其次,我们定义外层循环 for _ in range(k): 执行 k 次操作。每次操作前,重新计算列表的长度 n。
3、我们再利用内层循环 for i in range(n): 遍历列表中的每个元素。注意,如果当前元素是 '9',则将其设置为 '0',并在当前位置插入 '1';如果当前元素不是 '9',则将其加 1。
4、每次操作后,将列表转换回字符串 Str,然后再将字符串转换回列表 num_list,以便进行下一次操作。
5、经过 k 次操作后,将最终的列表转换为字符串,并将其转换为整数,最后对结果取模 MOD 后返回。
完整代码如下:
def solution(n, k, num_str):
MOD = 1000000007
# 转换为列表
num_list = list(num_str)
# 进行k次进位
for _ in range(k):
n = len(num_list)
for i in range(n):
if num_list == '9':
num_list == '0'
num_list.insert(i, '1')
else:
num_list[i] = str(int(num_list[i]) + 1)
Str = ''.join(num_list)
num_list = list(Str)
return int(''.join(num_list)) % MOD
运行代码可以看到结果是正确的: