整体思路:对于每一位,先将当前未达到limit部分的段 [如 0 ~ 10000] 直接处理好,到下一位时再处理达到limit的部分。
· 1 × 10 ^ n以内每个数(包括0)的出现次数的计算 [即已知bitnum[n - 1],求bitnum[n]]: 将bitnum[n - 1]乘以10,代表n - 1处最为每个小段在n处出现10次,再加上power10[n - 1],即加上新增的最高位该数出现次数。
· 1 × 10 ^ n以内0的出现次数的计算 [即已知bitzero[n - 1],求bitzero[n]]: 将bitzero[n - 1] + power10[n - 2] - 1 ··· ①,表示在n - 1的所有数(power10[n - 2] - 1)个前都加上一个前导零,再将① * 10,表示该小段出现10次。
· 处理limit位: 首先保存前n + 1位的limit位,那么前n + 1位的limit为在当前第n位的贡献即它们在0 ~ limit × 10 ^ n中每一大段停留的次数,即 [它们的出现次数 × power10[n - 1]]。
· 处理非limit位: 直接加上bitnum或bitzero(前导零情况)即可。
· 代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 5 using namespace std; 6 7 typedef long long LL; 8 9 const int MAXN = 10 + 5; 10 const int MAXM = 10; 11 12 LL power10[MAXN]; 13 14 LL bitnum[MAXN]; 15 LL bitzero[MAXN]; 16 17 void Preparation () { 18 power10[0] = 1; 19 for (int i = 1; i <= MAXM; i ++) 20 power10[i] = power10[i - 1] * 10; 21 22 bitnum[0] = 0; 23 for (int i = 1; i <= MAXM; i ++) 24 bitnum[i] = bitnum[i - 1] * 10 + power10[i - 1]; 25 26 bitzero[0] = 0, bitzero[1] = 1; 27 for (int i = 2; i <= MAXM; i ++) 28 bitzero[i] = (bitzero[i - 1] + power10[i - 2] - 1) * 10; 29 } 30 31 LL Answers[2][MAXM]; 32 33 int L, R; 34 35 int bit[MAXN]; 36 int N; 37 38 int cobit[MAXN]; 39 40 void separ (int p) { 41 memset (cobit, 0, sizeof (cobit)); 42 43 if (! p) 44 cobit[0] = 1; 45 while (p) { 46 cobit[p % 10] ++; 47 48 p /= 10; 49 } 50 } 51 52 void Solve (int M, int type) { 53 if (M <= 0) { 54 if (M == 0) 55 Answers[type][0] = 1; 56 57 return ; 58 } 59 60 int tmpM = M; 61 62 N = 0; 63 while (tmpM) { 64 bit[++ N] = tmpM % 10; 65 66 tmpM /= 10; 67 } 68 69 int bits = 0; 70 71 for (int i = N; i >= 1; i --) { 72 bits *= 10; 73 74 for (int j = 0; j < bit[i]; j ++) { 75 if (bits + j || i == 1) { // 处理limit位 76 separ (bits + j); 77 78 for (int k = 0; k <= 9; k ++) 79 Answers[type][k] += (LL) cobit[k] * power10[i - 1]; 80 } 81 82 for (int k = 1; k <= 9; k ++) 83 Answers[type][k] += bitnum[i - 1]; 84 Answers[type][0] += (bits + j ? bitnum[i - 1] : bitzero[i - 1]); 85 } 86 87 bits += bit[i]; 88 } 89 90 separ (M); 91 92 for (int k = 0; k <= 9; k ++) 93 Answers[type][k] += cobit[k]; 94 } 95 96 int main () { 97 Preparation (); 98 99 while (~ scanf ("%d%d", & L, & R) && L + R) { 100 if (L > R) 101 swap (L, R); 102 103 memset (Answers, 0, sizeof (Answers)); 104 105 Solve (L - 1, 0); 106 Solve (R, 1); 107 108 for (int i = 0; i <= 9; i ++) { 109 if (i) 110 putchar (' '); 111 112 printf ("%lld", Answers[1][i] - Answers[0][i]); 113 } 114 115 puts (""); 116 } 117 118 return 0; 119 } 120 121 /* 122 1 10 123 44 497 124 346 542 125 1199 1748 126 1496 1403 127 1004 503 128 1714 190 129 1317 854 130 1976 494 131 1001 1960 132 0 0 133 */