計算1到N中包含數字1的個數


 

轉自:http://pandonix.iteye.com/blog/204840 Mark

 

N為正整數,計算從1到N的所有整數中包含數字1的個數。比如,N=10,從1,2...10,包含有2個數字1。

 

相信很多人都能立刻得出以下的解法:

  for(n:N)

  {

          判斷n包含1的個數;

          累加計數器;

  }

這是最直接的解法,但遺憾的是,時間復雜程度為O(N*logN)。因為還需要循環判斷當前的n的各位數,該判斷的時間復雜程度為O(logN)。

接下來就應該思考效率更高的解法了。說實話,這道題讓我想起另外一道簡單的算法題:

N為正整數,計算從1到N的整數和。

很多人都采用了循環求解。然后利用初等數學知識就知道S=N*(N+1)/2,所以用O(1)的時間就可以處理。

再回到本道題目,同理應該去尋找到結果R與N之間的映射關系。

分析如下:

假設N表示為a[n]a[n-1]...a[1],其中a[i](1<=i<=n)表示N的各位數上的數字。

c[i]表示從整數1到整數a[i]...a[1]中包含數字1的個數。

x[i]表示從整數1到10^i - 1中包含數字1的個數,例如,x[1]表示從1到9的個數,結果為1;x[2]表示從1到99的個數,結果為20;

當a[1]=0時,c[1] = 0;

當a[1]=1時,c[1] = 1;

當a[1]>1時,c[1] = 1;

 

當a[2]=1時,c[2] = a[1] +1+ c[1] + x[1];

當a[2]>1時,c[2] = a[2]*x[1]+c[1]+10;

 

當a[3]=1時,c[3] = a[2]*a[1] +1+ c[2] + x[2];

當a[3]>1時,c[3] = a[3]*x[2]+c[2]+10^2;

......

 

以此類推

當a[i]=1時,c[i] = a[i-1]*...*a[1] +1+ c[i-1]+x[i-1];

當a[i]>1時,c[i] = a[i]x[i-1]+c[i-1]+10^(i-1);

 

代碼:

int main() { int N; cin>>N; int N1=N/10; int N2=N%10; int N3; int x=1; int y=10; int cnt=(N2==0?0:1); while(N1>0) { N3=N1%10; if (N3==0); else if (N3==1) { cnt=N2+1+x+cnt; } else { cnt=N3*x+cnt+y; } N2=10*N2+N3; N1=N1/10; x=10*x+y; y=y*10; } cout<<cnt<<endl; return 0; }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM