题目描述
求出113的整数中1出现的次数,并算出1001300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
解答:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//将整型数转化为字符数组
char* NumberChangeChar(int n)
{
if(n<0)
return 0;
char* str=(char*)malloc(sizeof(str)*100);
sprintf(str,"%d",n);
return str;
}
//函数功能10的n次方
int PowerBase10(unsigned int n)
{
int result=1;
unsigned int i=0;
for(i;i<n;++i)
{
result*=10;
}
return result;
}
int NumberO1(char* str)
{
//非法输入
if(!str||*str<'0'||*str>'9'||*str=='\0')
return 0;
int begin=*str-'0';//第一位数的值
unsigned int length=strlen(str);
//第一位为0
if(length==1&&begin==0)
return 0;
//只有一位
if(length==1&&begin>0)
return 1;
//最高位为1的情况下
int numFirstDig=0;
//若最高位大于1
if(begin>1)
numFirstDig=PowerBase10(length-1);
//若最高位小于1
else if(begin==1)
numFirstDig=atoi(str+1)+1;
//其余位为1的情况下
//例如21345,分两段(01346~11345)和(11346~21345)
//一共5位,第一位为2,除去第一位还剩四位,固定一位,其余三位在0~9中任意选择,即10^3,四次排列组合——2*4*10^3
int numOtherDig=begin*PowerBase10(length-2)*(length-1);
//递归
int numRecursive=NumberO1(str+1);
return numFirstDig+numOtherDig+numRecursive;
}
int main()
{
printf("%d\n",NumberO1(NumberChangeChar(21345)));
return 0;
}