首先观察N=123456的情况:
十万位1的个数: 23456+1 = 23457
万位 1的个数: (1+1)*10000 = 20000
千位 1的个数: (12+1)*1000 = 13000
百位 1的个数: (123+1)*100 = 12400
十位 1的个数: (1234+1)*10 = 12350
个位 1的个数: (12345+1)*1 = 12346
总数为: 93553
再看另一个N = 223456例子做比较:
十万位1的个数: 100000
万位 1的个数: (2+1)*10000 = 30000
千位 1的个数: (22+1)*1000 = 23000
百位 1的个数: (223+1)*100 = 22400
十位 1的个数: (2234+1)*10 = 22350
个位 1的个数: (22345+1)*1 = 22346
总数为: 220096
以上结果和其他的方法求出来的结果相同,我们可以看出其中的一些规律:
在讨论某一个数位上的1的个数的时候,可以以这个数位为界,将原数一分为二,个人在编程时,还将给出的数字分为尾数为0和不为0:
如果尾数为0:
1、如果当前数位上的数字为1,则1出现的次数为当前数位后面的数+1,再加上当前数位前面的数乘以后面的基数;
2、如果当前数位上的数字为1,则1出现的次数为当前数位前面的-1,再乘以后面的基数;
如果尾数不为0:
1、当前数位前面的数(如果当前数位上的数为0,需减1),乘以后面的基数。
然而,数字的最高位应该要特殊处理:如果最高位是1(与123456类似),就是依照上述规律处理;如果最高位大于1,则是上述基数的值(与223456类似)。
以上是借鉴别人的思路,但总感觉有点不太好理解,我自已分析整理出自已的思路,写出代码:
如求123104
十万位1的次数:100000
万位1的次数 :(1+1)*10000
千位1的次数 :(12+1)*1000
百位1的次数 :(123)*100+(4+1)
十位1的次数 :(1231)*10
个位1的次数 :12310+1
思路: 求出整数十进制表示中1在每一位上出现的次数
假设我们现在求一个整数任一一位上1出现的次数
1.如果当前位==1
if当前位不是最后一位 num1=当前位前几位表示的整数*后面的基数+后面的几位表示的整数+1;
if当前位是最后一位,num1=当前位前几位表示的整数+1;
2.如果当前位==0
if当前位不是最后一位,num1=当前位前几位表示的整数*后面的基数
if当前位是最后一位,num1=当前位前几位表示的整数
3.如果当前位>1
num1=(当前位前几位表示的整数+1)*后面的基数
代码如下
#include<iostream>
#include"string.h"
using namespace std;
int find_1(int n);
int num_of_1(int n)
{
int count=0;
for(int i=1;i<=n;i++)
count+=find_1(i);
return count;
}
int find_1(int n)
{
int count=0;
while(n>0)
{
if(n%10==1)
count++;
n=n/10;
}
return count;
}
//上面是最直接的方法,时间复杂度为o(n)
//以下是第二种思路的代码
//两种方法验证得到的1出现的位数是相同的
int pow10(int n)
{
int num=1;
for(int i=0;i<n;i++)
num=num*10;
return num;
}
int num_of_1(int n)
{
char *s=new char[50];
int flag=0,count=0;
sprintf(s,"%d",n);
int size=static_cast<int>(strlen(s));
for(int i=1;i<=size;i++)
{
//if('*s'<'0'||'*s'>9||'*s'=='\0')
// return count;
cout<<*s<<endl;
if(*s == '1')
{
if(i==6)
count+=(flag+1);
else
count+=flag*pow10(size-i)+(atoi(s+1)+1);
}
if(*s == '0')
{
if(i==6)
count+=(flag);
else
count+=(flag)*pow10(size-i);
}
if(*s > '1')
count+=(flag+1)*pow10(size-i);
flag=n/pow10(size-i);
s=s+1;
}
return count;
}
int main()
{
cout<<num_of_1(1304);
cout<<"--------------"<<endl;
cout<<num_of_1(1314);
//cout<<"--------------"<<endl;
//cout<<num_of_1(121);
}