首先觀察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);
}