题解
数字出现的次数
1 条题解
-
0
解题思路
两个大整数的位数都接近 1000 位,早就超过 long long 能存的范围了,所以要学一个专门的技能:高精度加法。
思路是:像我们平时在纸上列竖式算加法一样,从个位开始,一位一位加,满 10 就往前进 1。
具体做法:
- 把两个大数当字符串读进来。
- 倒着放进数组:个位放在下标 0,十位放在下标 1……这样从下标 0 开始就是"从低位往高位"算,非常方便。
- 逐位相加:s[i] = a[i] + b[i] + 进位。
- 如果某一位 >= 10,就减 10,并且下一位加 1(进位)。
- 加完后,统计数组里每一位等于 m 的个数,就是答案。
参考代码
// 用途:两个大整数相加,统计数字m(0~9)在和中出现的次数 // 大整数位数<1000,用字符数组读入,逐位相加存到数组 #include <iostream> using namespace std; int main() { char a[1005], b[1005]; int ca[1005] = {0}, cb[1005] = {0}, s[1005] = {0}; // 倒序存储的数组 int m; cin >> a >> b >> m; int la = 0, lb = 0; while (a[la]) la++; // a的位数 while (b[lb]) lb++; // b的位数 for (int i = 0; i < la; i++) ca[i] = a[la - 1 - i] - '0'; // 倒序存入 for (int i = 0; i < lb; i++) cb[i] = b[lb - 1 - i] - '0'; int len = (la > lb) ? la : lb; // 和的位数至少是较长的那个 for (int i = 0; i < len; i++) { // 逐位相加 s[i] += ca[i] + cb[i]; if (s[i] >= 10) { // 满10进位 s[i] -= 10; s[i + 1]++; } } if (s[len]) len++; // 最高位可能再进一位 int cnt = 0; for (int i = 0; i < len; i++) if (s[i] == m) cnt++; // 统计数字m出现的次数 cout << cnt; return 0; }复杂度分析
加法需要处理两个数每一位,设位数最多为 n(本题不超过 1000),时间复杂度是 O(n),空间复杂度是 O(n)。对于 1000 位的数来说完全没问题。
- 1