分治算法---计数问题

分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相对独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。

计数问题

题目描述
给定两个整数a和b,计算出1在a和b之间出现的次数。例如,如果a=1024,b=1032,那么a和b之间的数就是:
1024 1025 1026 1027 1028 1029 1030 1031 1032
则有10个1出现在这些数中。

输入:
输入不会超过500行,每一行有两个整数a和b,a和b之间的范围是0<a,b<100 000 000。输入两个0时程序结束,两个0不作为输入样例。
输出:
对于每一对输入的a和b,输出一个数,代表1出现的个数。
样例输出:
1 10
44 497
346 542
1199 1748
1496 1403
1004 503
1714 190
0 0
样例输出:
2
185
40
666
113
105
1133

解题思路
本题要求出1在两个整数a和b之间出现的次数。可以由分治算法的思想,先求出在0~a之间出现的次数,再求出在0-b之间出现的次数,然后两者相减即可。现在的问题转换为如何求出1在0-a之间出现的次数。
将0~197的数列出来后可看出以下规律:

  1. 可以求出1在190~197之间出现的次数,然后对与0-189,在个位数上出现了1次。
  2. 个位考虑完后直接考虑197/10-1(即18中)中1出现的次数,同时考虑到,数字减小了,每一位的权值会增加,也就是说每一个数字出现的次数会增加十倍。例如,现在的1,是原来10~19之间的所有的1,即权值变为原来的十倍。

参考程序

/*本算法计算出0~9在a和b之间出现的次数,取答案时直接取d[1]即可*/
#include <iostream>
using namespace std;
/***********************************/
const int N = 11;
int d
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值