给定两个数a和b,计算出1在a和b之间出现的次数。
解题思路:
可以由分治算法的思想,先求出1在0~a中出现的次数,再求出1在0~b中出现的次数,然后两者相减即可。
1 #include<stdio.h>
2 int d[ 11]; // d[n]存储数字0~9分别出现的次数。
3 int value; // 记录相应的权值变化
4 void deal( int n)
5 {
6 if(n<= 0)
7 return;
8 int one,ten; // one,ten分别代表个位和十位、
9 one=n% 10;
10 n/= 10;
11 ten=n;
12 int i;
13 for(i= 0;i<one;i++) // 将个位上出现的数统计下来
14 d[i]+=value;
15 while(ten)
16 {
17 d[ten% 10]+=(one+ 1)*value;
18 ten/= 10;
19 }
20 for(i= 0;i< 10;i++)
21 d[i]+=value*n;
22 d[ 0]-=value; // 将第一位是0的情况排除
23 value*= 10; // 权值变化,变为原来的10倍
24 deal(n- 1);
25 }
26 int main()
27 {
28 int a,b,i;
29 while(scanf( " %d%d ",&a,&b))
30 {
31 if(a== 0&&b== 0)
32 break;
33 if(a<b)
34 {
35 int temp=b;
36 b=a;
37 a=temp;
38 }
39 for(i= 0;i< 11;i++)
40 d[i]= 0;
41 value= 1;
42 deal(a);
43 value=- 1; // 此处value=-1是为了求出最后的答案deal(a)-deal(b)
44 deal(b- 1);
45 printf( " %d\n ",d[ 1]);
46 }
47 return 0;
48 }
2 int d[ 11]; // d[n]存储数字0~9分别出现的次数。
3 int value; // 记录相应的权值变化
4 void deal( int n)
5 {
6 if(n<= 0)
7 return;
8 int one,ten; // one,ten分别代表个位和十位、
9 one=n% 10;
10 n/= 10;
11 ten=n;
12 int i;
13 for(i= 0;i<one;i++) // 将个位上出现的数统计下来
14 d[i]+=value;
15 while(ten)
16 {
17 d[ten% 10]+=(one+ 1)*value;
18 ten/= 10;
19 }
20 for(i= 0;i< 10;i++)
21 d[i]+=value*n;
22 d[ 0]-=value; // 将第一位是0的情况排除
23 value*= 10; // 权值变化,变为原来的10倍
24 deal(n- 1);
25 }
26 int main()
27 {
28 int a,b,i;
29 while(scanf( " %d%d ",&a,&b))
30 {
31 if(a== 0&&b== 0)
32 break;
33 if(a<b)
34 {
35 int temp=b;
36 b=a;
37 a=temp;
38 }
39 for(i= 0;i< 11;i++)
40 d[i]= 0;
41 value= 1;
42 deal(a);
43 value=- 1; // 此处value=-1是为了求出最后的答案deal(a)-deal(b)
44 deal(b- 1);
45 printf( " %d\n ",d[ 1]);
46 }
47 return 0;
48 }