给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。
解题思路
对于大范围 内的数字统计,需要使用数位DP的方法:
-
将问题转化为求
,表示
到
中每个数字出现的次数
- 则区间
的答案为
- 则区间
-
对于计算
:
-
考虑每一位的贡献
-
例如对于数字
:
- 个位:每
个数,
各出现
次
- 十位:每
个数,每个数字在十位上出现
次
- 百位:每
个数,每个数字在百位上出现
次
- 千位:
出现
次,
出现
次,
出现
次
- 个位:每
-
-
核心思路:
- 对每一位,计算该位上的每个数字出现次数
- 需要考虑当前位是否受限
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void (async function () {
// Write your code here
let params = [];
while ((line = await readline())) {
let tokens = line.split(" ");
// let a = parseInt(tokens[0]);
// let b = parseInt(tokens[1]);
// console.log(a + b);
params.push(tokens);
}
// console.log(params)
let start = parseInt(params[0][0]);
let end = parseInt(params[0][1]);
function count(n) {
let pos = 1;
let cnt = new Array(10).fill(0);
while (n >= pos) {
let high = Math.floor(n / (pos * 10));
let curr = Math.floor(n / pos) % 10;
let low = n % pos;
// console.log(high, curr, low);
for (let digit = 0; digit < 10; digit++) {
cnt[digit] += high * pos;
if (digit < curr) {
cnt[digit] += pos;
} else if (digit === curr) {
cnt[digit] += low + 1;
}
if (digit === 0) {
cnt[0] -= pos;
}
}
pos *= 10;
}
return cnt;
}
let arr1 = count(start - 1);
let arr2 = count(end);
let str = "";
for (let i = 0; i < arr1.length; i++) {
str += Math.abs(arr1[i] - arr2[i]) + " ";
}
console.log(str);
})();