分治算法-计算问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34432960/article/details/61428085

题目:本题要求出 1 在两个数 a 和 b 之间出现的次数。可以用分治算法的思想,先求出 1 在 0~a 之间出现的次数,再求出 1 在 0~b 之间出现的次数,然后两者相减即可。现在的问题是如何求出 1 在 0~a 之间出现的次数。将 0~197 的数列列出后可以看出规律:
可以求出 1 在 190~197 之间出现的次数,然后考虑 1 在 0~189 之间出现的次数。190~197 中 1 在各位上出现了1 次。
个位考虑完后,直接考虑 197/10-1 (即18)中出现的次数,同时考虑,数字减小了,每一位的权值会增加,也就是说每一个数字出现的次数会增加 10 倍。

例如,现在的 1,是原来的 10~19 之间的所有的 1 ,即权值变为了原来的 10 倍。输入要求:输入不会超过500行。每行输入两个数a和b,a和b的范围是:0~100 000 000。输入两个0时程序结束。详见输入样例。输出要求:对于每一对输入的a和b,输出一个数,表示1出现的个数。详见输出样例。输入输出样例:
输入
1 10
44 497
346 542
1199 1748
1496 1403
1004 503
1714 190
1317 854
1976 494
1001 1960
0 0
Output sample:
2
185
40
666
113
105
1133
512
1375
1256

/注释以计算0~197之间各数出现次数的概率为例/“`

include

using namespace std;
/*******************************/
const int N = 11;
void deal(int n);
int value;
int d[N]; //这里的d[n],存储0~9在两个数之间出现的次数,输出时只要输出d[1];就好了
/********************************/
void deal(int n) //注释以197为例;
{
if(n<=0)return;
int one,ten;
one = n%10;
n/=10;
ten = n;
int i;
for (i=0;i<=one;i++) //个位出现各个数的次数;
{
d[i]+=value;
}
while (ten) //记10位和百位上分别出现9,1时,9,1,
//出现的次数,因为当前两位是19时,1,9的权值
//要分别加上one+1;
{
d[ten%10]+=(one+1)*value;
ten/=10;
}
for(i =0;i<10;i++) //算前两位为0~18时个位出现的不同数的个数,并跟之前的相加;
d[i]+=value*n;
d[0]-=value; //前两位不能为0
value*=10;
deal(n-1);

}
int main()
{
int a,b,i ;
int tmp;
while(cin>>a>>b)
{
if(a==0&&b==0)
{
cout<<”pay attention to your input”<

猜你喜欢

转载自blog.csdn.net/qq_34432960/article/details/61428085
今日推荐