P2602 [ZJOI2010]数字计数
1 #include <bits/stdc++.h> 2 #define ll long long 3 #define re register 4 using namespace std; 5 6 template <typename T>void in(T &x) { 7 x = 0; T f = 1; char ch = getchar(); 8 while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();} 9 while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();} 10 x *= f; 11 } 12 13 template <typename T>void out(T x) { 14 if(x < 0) x = -x,putchar('-'); 15 if(x > 9) out(x/10); 16 putchar(x%10 + 48); 17 } 18 //--------------------------------------------------------- 19 const int N = 20; 20 ll a,b; 21 ll f[N][N]; 22 int num[N]; 23 24 ll dfs(int pos,int lead,int limit,int digit,int sum) { 25 if(pos == 0) return sum;//边界 26 if(lead && !limit && f[pos][sum] != -1) return f[pos][sum]; 27 //先导不为0 未受限 已算过 -> 返回 28 ll res = 0; 29 int up = (limit == 1 ? num[pos] : 9); 30 //int up = 9; if(limit) up = num[pos]; 31 for(int i = 0; i <= up; ++i) { 32 res += dfs(pos-1,lead|i,(i==up)&&(limit),digit,sum+((lead|i)&&(i==digit))); 33 } 34 if(lead && (!limit)) f[pos][sum] = res; 35 return res; 36 } 37 38 ll solve(ll x,int digit) { 39 int len = 0; 40 while(x) num[++len] = x%10,x/=10;//逆序存数; 41 memset(f,-1,sizeof(f)); 42 dfs(len,0,1,digit,0); 43 } 44 45 int main() { 46 in(a); in(b); 47 for(int digit = 0; digit <= 9; ++digit) { 48 out(solve(b,digit) - solve(a-1,digit)); putchar(' '); 49 } 50 return 0; 51 }