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("\n");

65     }

66 

67     return 0;

68 }
代码君

 

你可能感兴趣的:(count)