整数中1出现的次数(从1到n整数中1出现的次数)

  • 时间限制:1秒空间限制:32768K
  • 通过比例:22.83%
  • 最佳记录:0 ms|8552K(来自  sliver)

题目描述

求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。

题目链接:http://www.nowcoder.com/practice/bd7f978302044eee894445e244c7eee6?rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

其实是个简单的问题,就是需要你仔细一点;把每一位数含有1的个数累加,然后处理边界就可以了;

面试题,关键是仔细!

#include<stdio.h>
class Solution {
public:
    int NumberOf1Between1AndN_Solution(int n)
    {
        int a[50]={0};
        int cnt=0;
        int m=n;
        while(n)
        {
            a[cnt++]=n%10;
            n/=10;
        }
        int k=0;
        int ans=0,tmp=1;
        int b[50]={0};
        b[0]=0;
        while(k<cnt-1)
        {
            if(k==0)b[k]=1;
            else b[k]+=9*b[k-1]+ppow(10,k);
    //        printf("b[%d]=%d\n",k,b[k]);
            k++;
            b[k]=b[k-1];
        }
        for(int i=cnt-1;i>0;i--)
        {
            if(a[i]==1) {ans+=m%ppow(10,i)+1;}
            for(int j=a[i]-1;j>=0;j--)
            {
                if(j==1) ans+=ppow(10,i);
                ans+=b[i-1];
            }
        }
        if(a[0]>=1) ans++;
        return ans;

    }
    int ppow(int a,int b)
    {
        int c=1;
        while(b)
        {
            if(b&1)c=c*a;
            b>>=1;
            a=a*a;
        }
        return c;
    }
};
int main()
{
    int n;
    Solution so;
    while(~scanf("%d",&n))
    {
        int ans=so.NumberOf1Between1AndN_Solution(n);
        printf("%d\n",ans);
    }
}


你可能感兴趣的:(模拟,递推,剑指offer)