LFYZ-OJ ID: 1019 位數問題


位數問題

問題描述

在所有的N位數中,有多少個數中有偶數個數字3?由於結果可能很大,你只需要輸出這個答案對12345取余的值。

INPUT

輸入一個數N(1<=N<=1000),輸入以0結束。

OUTPUT

對於每一個N輸出有多少個數中有偶數個數字3。

Sample Input

2
0

Sample Output

73

分析

已知N的最大值為1000,1000位的數字的個數約有101000個,這是個天文數字,故不可能使用枚舉法一一統計。本題需使用遞推的思想:

設E(n)為n位數中有偶數個3的數字個數,O(n)為n位數中有奇數個3的數字個數。從n位數轉變為n+1位數可以在n位數的基礎上增加一位:

偶數的英文為“Even”, 奇數的英文為“Odd”,在這里“O(n)”可能會和時間復雜度的概念混淆,小心避免理解出錯。

  • 如果n位數中有偶數個3,新增一個數位為3,則n+1位數中有奇數個3
  • 如果n位數中有偶數個3,新增一個數位為非3,則n+1位數中有偶數個3
  • 如果n位數中有奇數個3,新增一個數位為3,則n+1位數中有偶數個3
  • 如果n位數中有奇數個3,新增一個數位為非3,則n+1位數中有奇數個3

遞推關系用公式表達如下:

  • E(n+1)=E(n)*9+O(n) => E(n)=E(n-1)*9+O(n-1)
  • O(n+1)=E(n)+O(n)*9 => O(n)=E(n-1)+O(n-1)*9

1位數有10個:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 數字3中有奇數個(1個)數字3,其它9個數字中有偶數個(0個)數字3,因此E(1)=9, O(1)=1,這就是遞推的已知條件,也是我們遞推的起點。但在遞推的時候,數字的第一位是不能為0的,所以遞推到第一位(我們從低位往高位推)時,不是乘9,而是乘8。

當N很大時,數字必定會超過int能夠表達的范圍從而導致溢出,所以在遞歸過程中要不斷的按照題目要求和12345求余以將數字控制在一定范圍內。

通過遞推計算,時間復雜度為O(N)。

代碼示例

#include<iostream>
using namespace std;
int EVEN[1001], ODD[1001];		//Even存儲偶數項,ODD存儲奇數項
int main(){
	int N, x=9;
	scanf("%d", &N);
	EVEN[1]=9;                  //遞推起點
	ODD[1] =1;                  //遞推起點
	for(int i=2; i<=N; i++){
		if(i==N) x=8;           //遞推到最高項時
		EVEN[i]=(EVEN[i-1]*x+ODD[i-1])%12345;
		ODD[i] =(EVEN[i-1]+ODD[i-1]*9)%12345;
	}
	printf("%d", EVEN[N]);
} 


免責聲明!

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



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