nyoj 1的个数 514 (数学)

来源:互联网 发布:做表情包软件 编辑:程序博客网 时间:2024/06/05 02:00

1的个数

时间限制:1000 ms  |  内存限制:65535 KB
难度:3
描述
给你两个数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 <= 100000000。输入两个0时程序结束,两个0不作为输入样例。
输出
对于每一对输入的a和b,输出一个数,代表1出现的个数。
样例输入
1 1044 497346 5420 0
样例输出
218540
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;long long f(long long x){if(x<0)return 0;long long t=0,p=1,tmp=x;while(x>0){if(x%10==0)t+=x/10*p;else{if(x%10==1){if(x==tmp)t+=x/10*p+1;else t+=tmp%p+1+x/10*p;}elset+=(x/10+1)*p;}x/=10;p*=10;}return t;}int main(){long long a,b,t;while(scanf("%lld%lld",&a,&b),a|b){if(a<b){t=a;a=b;b=t;}printf("%lld\n",f(a)-f(b-1));}return 0;} 


//添加了具体思路

#include<stdio.h>#include<string.h>#define ll long longll f(ll x){ll t=0,p=1,tmp=x;//t表示1的个数,p表示位数(个、十,百...位) if(x<0)return 0;while(x>0){if(x%10==0)//如果数的个位为0, t+=x/10*p;//那么个位上的1的个数为x/10*p个 else//个位的数不为0. {if(x%10==1)//如果个位数为1 {if(x==tmp)//先判断x的值是否更新过,若没有 t+=x/10*p+1;//则此时个位上的1的个数为x/10*p+1。 else//如果x的值更新过 t+=tmp%p+1+x/10*p;//这块算的就不是个位上1的个数了,而是十位、百位...上的1的个数 }else//如果个位上的数不为1 t+=(x/10+1)*p;//那么个位上的数为(x/10+1)*p }x/=10;//更新x的值。 p*=10;//更新p的值(由个位变为十位...) }return t;}int main(){ll x,y,t;while(scanf("%lld%lld",&x,&y),x|y){if(x<y){t=x;x=y;y=t;}printf("%lld\n",f(x)-f(y-1));}return 0;} 



 

0 0