给定两个数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 }