数字0-9的数量 数位dp

时间:2021-11-06 10:06:46

给出一段区间a-b,统计这个区间内0-9出现的次数。
比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次。
Input
两个数a,b(1 <= a <= b <= 10^18)
Output
输出共10行,分别是0-9出现的次数
Sample Input
10 19
Sample Output
1
11
1
1
1
1
1
1
1
1

先看这道题
数字0-9的数量 数位dp


int main() {
ll ans = 0, n;
cin >> n;
for (ll i = 1; i <= n; i *= 10) { // 对于n的每一位,置1
// 一个数 12c45
// 比如把 第三位c 置1,用x代替,此时 12x45 a = 12c,b = 45
//①如果c<=1 这个时候,x前的数字可以为0 - 11 共12个,x后的数字为0 - 99 即 ans += 12 * 100
// 此时,如果c==1,x前的数字可以为12,x后的数字为0-b,即 ans += (b+1);
//②如果c>1 这个时候,x前的数字可以为0 - 12 共13个,x后的数字为0 - 99 即ans += 13 * 100


ll a = n / i, b = n % i;
ans += (a + 9 - 1) / 10 * i + (a % 10 == 1 ? 1 : 0) * (b + 1);
}
cout << ans << endl;
}

理解之后,那么0-9的数量就很好求了,处理0的时候,注意一下不能有前置0就好了。


#include <bits/stdc++.h>
using namespace std;

const int INF = 0x3f3f3f3f;
const int maxn = 1000008;
const int Mod = 1e9 + 7;

#define ll long long
#define mem(x,y) memset(x,y,sizeof(x))
#define IO ios_base::sync_with_stdio(0), cin.tie(0);

inline ll gcd(ll a, ll b) {return a % b == 0 ? b : gcd(b, a % b);}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}

int main() {
ll n, m, ans[10];
while (cin >> m >> n) {
m--;
mem(ans, 0);
for (ll j = 0; j < 10; j++) {
for (ll k = 0; k <= log10(n); k++) {
ll x = pow(10, k);
ll a = n / x, b = n % x;
if (j)
ans[j] += (a + 9 - j) / 10 * x + (a % 10 == j ? 1 : 0) * (b + 1);
else ans[j] += ((a + 9 - j) / 10 - 1) * x + (a % 10 == j ? 1 : 0) * (b + 1);
}
}
for (ll j = 0; j < 10; j++) {
for (ll k = 0; k <= log10(m); k++) {
ll x = pow(10, k);
ll a = m / x, b = m % x;
if (j)
ans[j] -= (a + 9 - j) / 10 * x + (a % 10 == j ? 1 : 0) * (b + 1);
else ans[j] -= ((a + 9 - j) / 10 - 1) * x + (a % 10 == j ? 1 : 0) * (b + 1);
}
}
for (int i = 0; i < 10; i++)
cout << ans[i] << endl;
}
}