题目
给出一段区间a-b,统计这个区间内0-9出现的次数。
比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次
输入
两个数a,b(1 <= a <= b <= 10^18)
输出
输出共10行,分别是0-9出现的次数
输入样例
10 19
输出样例
1 11 1 1 1 1 1 1 1 1
代码
1 import java.util.*; 2 3 public class Main { 4 5 static long a, b; 6 static Scanner scan = new Scanner(System.in); 7 static long[][][] f = new long[25][10][10]; 8 9 public static void init() { 10 for (int i = 0; i < 10; ++i) { 11 f[1][i][i] = 1; 12 } 13 14 for (int i = 2; i < 25; ++i) { 15 for (int j = 0; j < 10; ++j) { 16 for (int k = 0; k < 10; ++k) { 17 if (j == k) { 18 f[i][j][k] += (long) Math.pow(10, i - 1); 19 } 20 for (int p = 0; p < 10; ++p) { 21 f[i][j][k] += f[i - 1][p][k]; 22 } 23 } 24 } 25 } 26 27 } 28 29 30 public static long[] dp(long n) { 31 long[] res = new long[10]; 32 ArrayList<Integer> last = new ArrayList<Integer>(); 33 34 if (n == 0) { 35 res[0] += 1; 36 return res; 37 } 38 39 40 ArrayList<Integer> nums = new ArrayList<Integer>(); 41 while (n > 0) { 42 nums.add((int) (n % 10)); 43 n /= 10; 44 } 45 // 46 47 for (int i = nums.size() - 1; i >= 0; --i) { 48 int x = nums.get(i); 49 if (i == nums.size() - 1) { 50 for(int p=i;p>=0;--p){ 51 res[0]-=(long)Math.pow(10,p); 52 } 53 // res[0] -= (long) Math.pow(10, i); 54 // res[0] -= (long) Math.pow(10, i); 55 } 56 for (int j = 0; j < x; ++j) { 57 for (int p = 0; p < 10; ++p) { 58 res[p] += f[i + 1][j][p]; 59 } 60 for (int t : last) { 61 res[t] += (long) Math.pow(10, i); 62 } 63 } 64 65 last.add(x); 66 if (i == 0) { 67 for (int t : last) { 68 res[t] += 1; 69 } 70 71 } 72 } 73 return res; 74 75 } 76 77 public static void main(String[] args) { 78 a = scan.nextLong(); 79 b = scan.nextLong(); 80 81 init(); 82 long[] res1 = dp(b); 83 long[] res2 = dp(a - 1); 84 for (int i = 0; i < 10; ++i) { 85 res1[i] -= res2[i]; 86 } 87 88 for (long t : res1) { 89 System.out.println(t); 90 } 91 92 93 } 94 95 }
总结
关键是把dp搞对,然后注意细节部分,比如这道题中的前导0(崩溃)