30.從1到n的正數中1出現的次數

 

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

       

 

       

       

}


 

                

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章