计数问题—分治

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

 

转载于:https://www.cnblogs.com/pony1993/archive/2012/05/30/2525832.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值