数1

题目:给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数。

要求:写一个函数 f(N) ,返回1 到 N 之间出现的 “1”的个数。例如 f(12)  = 5。
  
一、设计思想
  通过归纳法,可以发现:

  假设N = abcde,这里a,b,c,d,e分别是十进制数N的各个数位上的数字。如果要计算百位上出现1的次数,将受3方面因素影响:百位上的数字,百位以下(低位)的数字,百位(更高位)以上的数字。

  如果百位上的数字为0,则可以知道百位上可能出现1的次数由更高位决定,比如12 013,则可以知道百位出现1的情况可能是100-199,1 100-1 199,……,11 100-11 199,一共有1 200个。也就是由更高位数字(12) 决定,并且等于更高位数字(12)×当前位数(100)。

  如果百位上的数字为1,则可以知道,百位上可能出现1的次数不仅受更高位影响,还受低位影响,也就是由更高位和低位共同决定。例如12 113, 受更高位影响,百位出现1的情况是100-199,1 100-1 199,……,11 100-11 199,一共有1 200个,和上面第一种情况一样,等于更高位数字(12)×当前位数(100)。但它还受低位影响,百位出现1的情况是12 100-12 113,一共114个,等于低位数字(113)+1。

  如果百位上数字大于1(即为2-9),则百位上可能出现1的次数也仅由更高位决定,比如12 213,则百位出现1的情况是:100-199,1 100-1 199,……,11 100-11 199,12 100-12 199,共1300个,并且等于更高位数字+1(12+1)×当前位数(100)。

三、源代码

#include<iostream.h>
int main()
{
    int N,num,num1;
    cout<<"输入数字";
    cin>>N;
    num=N;
    num1=N;
    int p=0;
    int a[10];
    while(1)
    {
        if(num<10)
        {
            break;
        }
        a[p++]=num%10;
        num=num/10;
    }
    a[p++]=num;
    int i=0;

    int t=1;
    int s=1;
    int sum=0;
    int o=0;
    int l=1;
    for(i=0;i<p-1;i++)
    {
        if(i>0)
        {

        o=a[i-1]*l+o;
        l=l*10;
        }

        if(a[i]>1)
        {
           sum=sum+(num1/10+1)*s;
        }


        if(a[i]==1)
        {
            sum=sum+(num1/10)*s+o+1;
        }

        if(a[i]==0)
        {
            sum=sum+(num1/10)*s;
        }
        num1=num1/10;
        s=s*10;
    //cout<<sum;
    }
    for(i=0;i<p-1;i++)
    {
        t=t*10;
    }
    if(a[p-1]>1)
    {
        sum=sum+t;
    }
    else
    {
        if(a[0]>1)
        {
            sum=sum+N-t+1;
        }
        else
        {
            sum=sum+N-t;
        }

    }

    cout<<"1的个数为"<<sum<<endl;


    return 0;
}

四、截图 

五、总结

此次实验就是列举找寻规律,由规律写程序,其实规律出来后就很简单了。

posted on 2015-06-17 16:03  博客找田雨  阅读(483)  评论(0编辑  收藏  举报