原题链接:
题解:
采用分类讨论和前缀和的思想,分为以下几种情况:
需要注意的是,0不能作为最高位,也即当左部l==0时,我们考虑的是最高位,而0不能在最高位,例如统计1234这个四位数最高位上0出现的次数,显而易见,0234这种存在前导零的数并不存在。
代码:
#include<bits/stdc++.h>
using namespace std;
int tag(int x) {
int res = 0;
while (x) {
x /= 10;
res++;
}
return res;
}
int cnt(int v, int x) {
int res = 0, n = tag(v);
for (int i = 0;i < n;i++) {//i代表统计的值,0~9
//j为当前考虑位置的值,p为权重,l为左部,r为右部(当在最高位时,l==0)
//例如对于1047而言,若j指向从右向左第2个位置(下标为1)处,j=4,l=10,r=7,p=10
int p = pow(10, i), l = v / p / 10, r = v % p, j = v / p % 10;
if (l || x) {//零不能在最高位
if (x) res += l * p;//当统计的值非0,直接左部*权重
else res += (l - 1) * p;//当统计的值为0且左侧不为0时,考虑到前导0的存在,(左部-1)*权重
if (j == x) res += r + 1;//2种情况
else if(x<j) res += p;
}
}
return res;
}
int main() {
int a, b;
cin >> a >> b;
while (a && b) {
if (a > b) swap(a, b);
for (int i = 0;i < 10;i++)
cout << cnt(b, i) - cnt(a - 1, i) << " ";
cout << endl;
cin >> a >> b;
}
}