1 条题解
-
0
📝 题目大意
有一个收银机,初始显示为 。有 个按钮:
00(将当前数字乘 )和0~9(将当前数字乘 再加该数字)。给定目标整数 (以字符串形式给出,长度可达 ),求最少按键次数。💡 解题思路
-
题目分析:
- 的长度上限为 ,远超过 位整数范围,必须用字符串处理。
- 每次按键本质上是在当前数字的末尾拼接若干位:按
0~9拼接 位,按00拼接 位(两个 )。 - 因此问题转化为:给定字符串 ,每次可以消耗 次操作输出 个字符,或者消耗 次操作输出连续的两个
0(即00按钮),求最少操作次数。
-
算法推导:
- 设 的长度为 (对应代码中的
n),答案初始为 (对应代码中的ans)。 - 从左到右扫描 (下标 从 到 ):
- 若当前字符
s[i]和下一个字符s[i+1]均为'0',则可以使用一次00按钮同时处理这两个字符:i++跳过下一个字符,ans++。 - 否则,当前字符只能单独用一个按钮处理:
ans++。
- 若当前字符
- 贪心正确性:遇到连续两个
0时使用00按钮,比分别用两次0按钮节省 次操作,且不会影响后续字符的匹配(因为00按钮恰好消耗相邻的两个0),不存在"拆开更优"的情况。
- 设 的长度为 (对应代码中的
-
边界与细节:
- 当 (最后一个字符)时,
s[i+1]为字符串结束符'\0',不等于'0',自动走else分支,不会越界。 - 注意
i++在if体内执行后,for循环的i++还会再执行一次,因此总共跳过了两个字符,逻辑正确。
- 当 (最后一个字符)时,
⏱️ 复杂度分析
- 时间复杂度:,其中 为字符串 的长度,仅需一次线性扫描。
- 空间复杂度:,用于存储输入字符串 。
💻 标准代码 (C++)
#include<bits/stdc++.h> using namespace std; int main() { string s; cin >> s; // 以字符串读入 S(因为可能超出 64 位整数范围) int n = s.size(), ans = 0; // n: 字符串长度, ans: 最少按键次数 for(int i = 0; i < n; i++) { // 若当前和下一个字符都是 '0',可以用一次 "00" 按钮处理两个字符 if(s[i] == '0' && s[i + 1] == '0') i++; // 跳过下一个字符 ans++; // 无论用 "00" 还是单个数字按钮,都消耗 1 次操作 } cout << ans; return 0; } -
- 1
信息
- ID
- 664
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者