POJ 3286 How many 0's?(数论)

来源:互联网 发布:网络就绪指数 编辑:程序博客网 时间:2024/06/15 12:56

Description
给两个32位无符号型整数n和m,保证m<=n,问从m到n中的所有整数中(包括n和m),每个数所包含的0的个数的和
Input
多组输入,每组用例两个无符号整形m和n,以-1 -1结束输入
Output
对于每组用例,输出区间[m,n]中所有数所包含0的个数
Sample Input
10 11
100 200
0 500
1234567890 2345678901
0 4294967295
-1 -1
Sample Output
1
22
92
987654304
3825876150
Solution
首先转化成求 [0, x] 中所有数中,含有的0的个数
对于一个数x,限制每一位是 0,然后再来计算。举个例子,假设x是 21035
首先0肯定是一个,sum赋初值为 1
个位数是0,个位数前面的数不能是0,能够取的数就是 [1, 2103],个位后面没有了,那么 sum+=2103*1
十位数是0,十位数前面的数不能是0,能够取的数就是 [1, 210],由于 0 比 3 小,十位后面可以取 [0, 9],那么 sum+=210*10
百位数是0,百位数前面的数不能是0,能够取的数就是 [1, 21],由于 0 是等于0的,这里就要特殊处理下了:
百位数前面的数如果是在 [1, 20] 中的一个数,百位数后面的数可以取的就是 [0, 99]
百位数前面的数如果取的是 21,百位数后面的数就只能取 [0, 35]
那么,sum+=20*100+36
以此类推即可
Code

#include<stdio.h>typedef long long ll;ll init(ll m){    ll sum=0,k=10,k1=1;    while(m/k)    {        sum+=(m/k*k1);        if((m/k1)%10==0)            sum-=(k1-1-m%k1);        k*=10;        k1*=10;    }    return sum;}int main(){    ll m,n,m1,n1;    while(scanf("%lld %lld",&m,&n)!=EOF)    {        if(m<0||n<0) break;        m--;        if(m<0) m1=-1;        else m1=init(m);        n1=init(n);        printf("%lld\n",n1-m1);         }    return 0;}
0 0
原创粉丝点击