题目描述:
给定一个十进制整数N,求出从1到N的所有整数中出现”1”的个数。
例如:N=2,1,2出现了1个“1”。
N=12,1,2,3,4,5,6,7,8,9,10,11,12。出现了5个“1”。
第二、分析该题目,通过举例,我们发现如下规律
给定一个十进制整数N,求出从1到N的所有整数中出现”1”的个数。
例如:N=2,1,2出现了1个“1”。
N=12,1,2,3,4,5,6,7,8,9,10,11,12。出现了5个“1”。
分析:
第一、最简单的思路:
从1到n的各个数,一个一个处理,复杂度是O(N*lnN)
<span style="font-family:SimSun;font-size:18px;">#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
int countOneNum(int n)
{
int ret=0;
while(n)
{
if(n%10==1)
{
ret+=1;
}
n/=10;
}
return ret;
}
int countOneNumSum(int n)
{
int total=0;
for(int i=1;i<=n;i++)
{
total+=countOneNum(i);
}
return total;
}
int main(int argc, const char * argv[])
{
int n=12;
cout<<countOneNumSum(n)<<endl;
getchar();
return 0;
}
</span>
第二、分析该题目,通过举例,我们发现如下规律
对于数abcde,c这位出现1的次数分以下情况;
1.若c>1,结论是(ab+1)*100
2.若c==1,结论是(ab)*100+de+1;
3.若c<1,结轮是 ab*100+de+1
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
int getPreInt(int n,int val)
{
while(val>10)
{
n/=10;
val/=10;
}
return n/10;
}
int getCurInt(int n,int val)
{
while(val>10)
{
n/=10;
val/=10;
}
return n%10;
}
int getPosInt(int n,int val)
{
return n%(val/10);
}
int countOneNum(int n)
{
int ret=0;
int val=10;
while(val<n*10)
{
int cur=getCurInt(n,val);
int pre=getPreInt(n,val);
int pos=getPosInt(n,val);
if(cur==0)
{
ret+=pre*val/10;
}else if(cur==1)
{
ret+=pre*val/10+pos+1;
}else
{
ret+=(pre+1)*val/10;
}
val*=10;
}
return ret;
}
int main(int argc, const char * argv[])
{
int n=123;
cout<<countOneNum(n)<<endl;
getchar();
return 0;
}