找"1"

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

要求:1.写一个函数f(N),返回1到N之间出现“1”的个数。例如f(12)=5。

        2.在32位整数范围内,满足条件的f(N)=N的最大N是多少。

#include<iostream>
using namespace std;

int search(int n)
{
    int a,m=10,k,x;
    
    x=0;
    k=n;
    do
    {
        a=k%10;

        if(a>1&&a<=9)
            x=x+(n/m+1)*m/10;
        else if(a==1)
            x=x+(n/m)*m/10+n%(m/10)+1;
        else if(a==0)
            x=x+(n/m)*m/10;

        m=m*10;
        k=(k-a)/10;
    }
    while(m<=(n*10));

    return x;
}
void main()
{
    int n,x,y,k;

    cout<<"输入一个整数:"<<endl;
    cin>>n;

    k=search(n);
    cout<<n<<"以内有"<<k<<"个1."<<endl;

    do
    {
        n++;
        y=search(n);
    }
    while(y==k);

    cout<<"含有"<<k<<"个1的最大整数为:"<<n-1<<endl;
    
}

 

思路:一1,个整数内有几个1和它每一位的数有关,即要判断个位,十位,百位各有多少个1。比如123这个数,它个位是3>1,那么这个数个位上就有1,11,21,31....121,

一共有13个“1”,十位是2>1,有10,11,12,13.....19;110,111,112.....119,一共20个“1”。百位是1,一共有100.....123,一共24个“1”。多列举几个数可以发现,每一位上分为三种情况:2~9,0和1;只要分别处理就行。

2~9:个位有(N/10+1)*1个;十位有(N/100+1)*10个,百位有(N/1000+1)*100个.......

1:个位有(N/10)*1+1个,十位有(N/100)*10+(N%10)+1个,百位有(N/1000)*100+(N%100)+1个....

0:有N/10个

感悟:一开始一直没有发现规律,一直做不出来,知道自己思路不对想改变思路,但还是会想着想着想回原来的思路,结果更乱了,心情也会烦躁。最后是睡了一觉,醒了之后就做出来了,不过可能还是可以优化。这次最大的感悟就是当发现自己思路不对时,不妨休息一下或与别人讨论讨论,自己硬想有时候只是浪费时间,钻牛角尖。当发现自己走进误区时一定要想办法走出来,而不是一味坚持己见。

posted @ 2015-06-05 16:35  夺命小五毛  阅读(194)  评论(0)    收藏  举报