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 10 44 497 346 542 0 0
样例输出
-
2 185 40
-
#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; } else t+=(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 long ll 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; }