UVa 1640 (计数) The Counting Problem

题意:

统计[a, b]或[b, a]中0~9这些数字各出现多少次。

分析:

这道题可以和UVa 11361比较来看。

同样是利用这样一个“模板”,进行区间的分块,加速运算。

因为这里没有前导0,所以分块的时候要多分几种情况。

以2345为例,这是一个四位数,首先要计算一下所有的一位数、两位数以及三位数各个数字出现的个数。

对应的模板分别为n,n*,n**,其中n代表非零数字,*代表任意数字。

考虑这样一个长为l的模板****(l个*),这样的数共10l个,而且各个数字都是等频率出现,所以每个数字出现的次数为l * 10l-1

统计完三位数一下的数字之后,就开始统计四位数字:1***,20**,21**,22**,230*,231*,232*,233*,2340,2341,2342,2343,2344,2345

在统计每个模板时,分这样两块计算:

  • **中该数字出现的次数
  • 前面该数出现的次数,比如22**,前面两个2会重复102
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 int pow10[10], cnt[10];
 7 
 8 int f(int d, int n)
 9 {
10     char s[15];
11     sprintf(s, "%d", n);
12     int len = strlen(s);
13     int ans = 0;
14 
15     for(int i = 1; i < len; i++)
16     {
17         if(i == 1) { ans++; continue; }
18         ans += 9 * cnt[i - 1];
19         if(d > 0) ans += pow10[i - 1];
20     }
21 
22     int pre[10];
23     for(int i = 0; i < len; i++)
24     {
25         pre[i] = (int)(s[i] - '0' == d);
26         if(i) pre[i] += pre[i - 1];
27     }
28 
29     for(int i = 0; i < len; i++)
30     {
31         int maxd = s[i] - '0' - 1;
32         int mind = 0;
33         if(i == 0 && len > 1) mind = 1;
34         for(int digit = mind; digit <= maxd; digit++)
35         {
36             ans += cnt[len - i - 1];
37             if(i) ans += pre[i - 1] * pow10[len - i - 1];
38             if(digit == d) ans += pow10[len - i - 1];
39         }
40     }
41     return ans;
42 }
43 
44 int main()
45 {
46     //freopen("in.txt", "r", stdin);
47 
48     pow10[0] = 1;
49     for(int i = 1; i <= 8; i++)
50     {
51         pow10[i] = pow10[i - 1] * 10;
52         cnt[i] = pow10[i - 1] * i;
53     }
54 
55     int a, b;
56     while(scanf("%d%d", &a, &b) == 2 && a && b)
57     {
58         if(a > b) swap(a, b);
59         for(int d = 0; d <= 9; d++)
60         {
61             if(d) printf(" ");
62             printf("%d", f(d, b+1) - f(d, a));
63         }
64         printf("
");
65     }
66 
67     return 0;
68 }
代码君
原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4318926.html