题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。
例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。
当最高位为1时:
如:1234 ,1的个数记为f(n)
分为两段,1~999,1000~1234
第一段:1~999 的个数 1*3*(10^2); 其中1为最高位,3为(长度-1),2为(长度-2)
第二段:1000~1234 的个数:f(234)+(234+1)
当最高位数不为1时:
如2254:分为两段:1~1999,2000~2254
第一段:2*3*(10^2)+10^3
第二段:f(254)
#include <stdio.h>
#include <stdlib.h>
//查找在1到N中 有多少个1
//比如 1,2,3...11,12 共有5个1
int Num1of1_nByStr(char *nstr,unsigned int);
int PowerBase10(unsigned int n);
int Num1of1_n(unsigned int n)
{
char nstr[50];
sprintf(nstr,"%u",n);
//printf("%s\n",nstr);
return Num1of1_nByStr(nstr,strlen(nstr));
}
int Num1of1_nByStr(char *nstr,unsigned int length)
{
if(!nstr|| length==0 || *nstr < '0' || *nstr > '9' || *nstr == '\0' )
return 0;
if(length ==1 )
{
if(*nstr==0)return 0;
else return 1;
}
int firstDigit=*nstr-'0';
if(firstDigit >1)
{
return PowerBase10(length-1) + firstDigit*(length-1)*PowerBase10(length-2)+Num1of1_nByStr(nstr+1,length-1);
}
else
{
return firstDigit*(length-1)*PowerBase10(length-2)+atoi(nstr+1)+1 + Num1of1_nByStr(nstr+1,length-1);
}
}
//10的n次方
int PowerBase10(unsigned int n)
{
int result = 1;
unsigned int i;
for(i = 0; i < n; ++ i)
result *= 10;
return result;
}
int main(void) {
printf("%d",Num1of1_n(1755322));
return EXIT_SUCCESS;
}