任重而道远
给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。
Input
输入文件中仅包含一行两个整数a、b,含义如上所述。
Output
输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次。
Sample Input
1 99
Sample Output
9 20 20 20 20 20 20 20 20 20
Hint
30%的数据中,a<=b<=10^6;
100%的数据中,a<=b<=10^12。
AC代码:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
#define ll long long
ll digit[15], dp[15][2][15][2];
ll a, b, cnt;
ll dfs (int dep, int sj, int x, ll sum, int zero) {
if (!dep) return sum;
if (dp[dep][sj][sum][zero]) return dp[dep][sj][sum][zero];
int i = sj ? digit[dep] : 9;
ll tmp = 0;
for (int k = i; k >= 0; k--) {
if ((k == x) && (k || !zero)) tmp += dfs (dep - 1, sj && (k == digit[dep]), x, sum + 1, zero && (k == 0));
else tmp += dfs (dep - 1, sj && (k == digit[dep]), x, sum, zero && (k == 0));
}
dp[dep][sj][sum][zero] = tmp;
return tmp;
}
ll solve (ll x, int i) {
memset (dp, 0, sizeof (dp));
memset (digit, 0, sizeof (digit));
cnt = 0;
while (x) {
digit[++cnt] = x % 10;
x /= 10;
}
return dfs (cnt, 1, i, 0, 1);
}
int main () {
cin >> a >> b;
for (int i = 0; i <= 9; i++) {
cout << solve (b, i) - solve (a - 1, i) << " ";
}
return 0;
}