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
-
/* 大神思路: 先讨论下1到n间的1的个数和。给你一个数如:384,求1~384的1的个数之和。 那么我只需求出1~300中1的个数和+1~80中1的个数和+1~4中1的个数和。 1~4的1的个数为1,1~80中1的个数为10^1(十位数)+8*10^0(个位数)----十位数有10,11,12,13....19(共10个数--其中11后面的1作为个位数看待),个位数为1,11,21,31...71,共有8个1,同理可得1~300中的1的个数102(百位数--只有以1开头的数)+3*101(十位数)+30*100(个位数)。 要特别注意的是当你的求的这一位是1的时候要特别处理,比方说N=187,这个时候百位上的1的个数就不是100了,而是88个即N%10^2+1。 化简以一下,求1~a000000(假设共有k位)中1的个数(a!=1),那么个数为:10^k-1+a*10^k-2+10*a*10^k-3+....+10^k-1*a*10^0=a*k*10^k-1(可视作a和其后任意一位不变的全排列) 那么我要求[a,b]间所有的1的个数和,那么就相当于求getNum(b)-getNum(a-1)的值。 */ #include <stdio.h> int pow[10] = {1,10,100,1000,10000,100000,1000000,10000000,100000000}; int getNum(int n) { int byte = 0, sum = 0, temp = n; if(n < 0) { return 0; } while(temp != 0) { if(temp%10 > 1) { sum += pow[byte]; } else if(temp % 10 == 1) { sum += (n%pow[byte]+1); } sum += temp%10*byte*pow[byte-1]; byte++; temp /= 10; } return sum; } int main() { int low, high; while(scanf("%d%d", &low, &high) && (low+high)) { if(low < high) { printf("%d\n", getNum(high)-getNum(low-1)); } else { printf("%d\n", getNum(low)-getNum(high-1)); } } return 0; }