30.在从1到n的正数中1出现的次数
题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。
题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。
例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。
分析:这是一道广为流传的google面试题。
/*
Name:
Copyright:
Author:
Date: 17-06-11 08:10
Description: 在从1到n的正数中1出现的次数(数组)
题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。
例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5
次。
分析:这是一道广为流传的google面试题。
*/
#include<iostream>
#include<iomanip>
using namespace std;
int *a;//a的含义,注释
int mpow(const int x,const int y)
{
if(0==y)
return 1;
else
{
int v=x;
for(int c=1;c<y;c++)
{
v*=x;
}
return v;
}
}
// c代表要计算到的位数,如一个四位数,需要计算到3位
void mak_a(int *const a,const int c)
{
a[1]=1;// 下标1代表1位数;0-9只有一个1 ;a[2]表示从10~99 出现1 的个数
int sum;
for(int i=2;i<=c;++i)
{
sum=0;
a[i]=mpow(10,i-1);
for(int j=1;j<i;++j)
{
sum+=a[j];
}
a[i]=a[i]+9*sum;
}
}
int mfun(char s[])
{
const int slen=strlen(s);
if(1==slen)
//只输入 1 或者 0的时候
{
if('0'==s[0])
{
return 0;
}
else
return 1;
}
else
{
int sum=0;
int i;
for(i=1;i<slen;++i)
{
if(s[i]!='0')
break;
}
for(int i=1;i<slen;++i)
{
sum+=a[i];
}
if('1'==s[0])
{
sum+=1+atoi(s+1);
}
else
{
sum=sum+mpow(10,slen-1)+(s[0]-'0'-1)*sum;
}
if(i!=slen)
sum+=mfun(s+i);
return sum;
}
}
int main()
{
int n;
cin>>n;
char s[15];
itoa(n,s,10);
a=(int *)malloc(sizeof(int)*strlen(s));
mak_a(a,strlen(s)-1);
int sum;
sum = mfun(s);
cout<<sum<<endl;
system("pause");
return 0;
}