题目大意:
给定你一个区间,要求你统计在这个区间中,每个数字位[0,9]出现的次数。
题目测试数据与数据范围:
23 123
20 44 21 21 20 20 20 20 20 20
223 1232314
712619 1055929 755323 714950 712620 712619 712619 712619 712619 712619
343 23235
8879 19879 13051 9069 8877 8880 8879 8879 8879 8879
1 2
0 1 1 0 0 0 0 0 0 0
0 0
数的范围可能比较大 a,b (0,10^9).
题目分折:
如果直接进行枚举输出,你一定会超时的,看来得有更好的解决方案。如果把一个数字的每一位分而治之,采用合理的正确的分治手段,我们一定能够达到目标。如果先处理个位,那如何才能取完所在的个位,而直接可以去统计它的更高位,我们以下面这个例子说明我们的方法。最大数为 197 。
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70
71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99 100
101 102 103 104 105 106 107 108 109 110
111 112 113 114 115 116 117 118 119 120
121 122 123 124 125 126 127 128 129 130
131 132 133 134 135 136 137 138 139 140
141 142 143 144 145 146 147 148 149 150
151 152 153 154 155 156 157 158 159 160
161 162 163 164 165 166 167 168 169 170
171 172 173 174 175 176 177 178 179 180
181 182 183 184 185 186 187 188 189 190
191 192 193 194 195 196 197
那么对于190-197 的数它的每一个(所有位)都可以统计出来。再来对 0-189 这些数的每个个位数都可以统计出来,那么剩下的就会成了这样的一个图(还清注意,留意一下 0 的变化有所不同,主要原因是因为我们已经处理了一次,不能再重复)。
1
1 1 1 1 1 1 1 1 1 2
2 2 2 2 2 2 2 2 2 3
3 3 3 3 3 3 3 3 3 4
4 4 4 4 4 4 4 4 4 5
5 5 5 5 5 5 5 5 5 6
6 6 6 6 6 6 6 6 6 7
7 7 7 7 7 7 7 7 7 8
8 8 8 8 8 8 8 8 8 9
9 9 9 9 9 9 9 9 9 10
10 10 10 10 10 10 10 10 10 11
11 11 11 11 11 11 11 11 11 12
12 12 12 12 12 12 12 12 12 13
13 13 13 13 13 13 13 13 13 14
14 14 14 14 14 14 14 14 14 15
15 15 15 15 15 15 15 15 15 16
16 16 16 16 16 16 16 16 16 17
17 17 17 17 17 17 17 17 17 18
18 18 18 18 18 18 18 18 18
其实就是每个数字有 10 个,这也是我们为什么等下要扩大 10 倍的原因。我们看到它变成了如下的一个问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
如是我们可以用相同的方法处理这个问题,难道不是吗? 把 10 到 18 的先处理,然后再处理 1-9 的个位,注意这里的统计量是要乘十的,相信原理你们会明白,上面的清楚。那么最后的问题就是 1 1 1 1 1 1 1 1,它等价于 1,只不过这个 1 是以百倍为计量。所以对于这个问题,我们的编程方法思路就是对给定的两个数,分别求出它们各自从 0 到本身每个 数出现的个数,相减即可。
小乐一下:
对于我们看待问题,要从多个方面去考虑问题,而且要有自己的思想,不能直接复制别人的,只有经过自己思考,花点时间自己思考,不要害怕花时间,因为这与你直接拿别人的代码敲一遍,有很大的差距,你懂得。自己的才是最好的。
我的代码,更好更简洁的由你来实现,不要直接自制。
#include<stdio.h>
int dp[10],values;
void account(int a){
int i,j;
if(a<=0) return;
int one = a % 10;
int ten = a/10;
a /= 10;
for(i = 0;i<=one;i++) dp[i] += values;
while(ten){
dp[ten%10] += (one + 1)* values;
ten/=10;
}
for(i = 0;i<=9;i++) dp[i] += a * values;
dp[0] -= values ;
values *= 10;
account(a-1);
}
int main(){
int a,b;
int i;
while(scanf("%d%d",&a,&b)!=EOF,a+b){
int temp;
if(a<b){temp = a;a = b;b = temp;}
for(i = 0;i<10;i++) dp[i] = 0;
values = 1;
account(a);
values = -1;
account(b-1);
for(i = 0;i<9;i++) printf("%d ",dp[i]);
printf("%d\n",dp[9]);
}
return 0;
}
伟大的梦想成就伟大的人,从细节做好,从点点滴滴做好,从认真做好。