1的个数

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;
}


你可能感兴趣的:(数学)