總時間限制:1000ms 記憶體限制:65536kb
描述給出乙個正整數a,要求分解成若干個正整數的乘積,即a = a1 * a2 * a3 * ... * an,並且1 < a1 <= a2 <= a3 <= ... <= an,問這樣的分解的種數有多少。注意到a = a也是一種分解。
輸入第1行是測試資料的組數n,後面跟著n行輸入。每組測試資料佔1行,包括乙個正整數a (1 < a < 32768)
輸出n行,每行輸出對應乙個輸入。輸出應是乙個正整數,指明滿足要求的分解的種數
樣例輸入
2
220
樣例輸出
1
4
i = 2~an,通過an%i ==0來判斷i是不是an的因數,如果是,則由an/i作為引數進一步帶入函式來判斷直至an/i == i,(此時i為最後乙個因數)。首先需知道f(m,n)的含義——求n中從m開始到n/m所有分解種數的和。而為什麼每次只要滿足上面的條件就算一種情況呢?這不妨舉個例子當n = 100時,2、50算一種情況,而50可以繼續分為2、25,這就有了2、2、25這種情況,再繼續分,且每次分都能成為其一種分解情況所以a++。
下面另一種寫法,區別在於分解次數加一是在每種分解情況完成時進行的,加的順序是從分解到的最小因子開始加起,如對n = 100時一次呼叫f(2, 50) ,然後f(2, 25) ,f(2, 5), f(5, 5) (每次呼叫到f(x, x),相當於一種情況,後面變成f(x,1)然後直接a++)則先是遞迴到2 2 5 5 a++ 後,回溯到f(2, 25), 再是f(25, 25)時相當於2 2 25的情況然後a++ ,然後在回溯到f(2, 50) , f(50, 50),a++,這樣對i ~ n/i中的分解情況累加。
再對for迴圈中的迴圈條件進行分析,他不會出現對兩個相同情況2 50 和 50 2重複a++, 當i = 50 時,呼叫f(50,2) (f(50, 100/2))時會直接不滿足條件而退出。而還要設i<=n, 是為了保證在回溯過程中將f(25, 25) 這樣的情況給加上。
而這種情況實現方法像上面提到的雖然不計算重複情況,但還是會執行判斷,會更耗時。
c++ac**:
#includeusing namespace std;
int a;
void f(int m, int n)
else for(int i = m; i <= n; ++i)
if(n % i == 0)}
int main()
}
而下面這種實現更是遞迴最典型的用法,是自頂向下的遞迴實現思路。從x開始向1遞迴,對1到x的每位進行判斷(是否是其最大因子)累加次數的同時,加上下次遞迴的f(a, b-1)的情況,f(a, b)中若a%b == 0 則,進一步遞迴分解。否者對b-1進行判斷。b減到1時結束返回0(可以想象乙個質數只有第一次加一,後面b一直在減一,直到b == 1則返回0),而被分解的數a等於1,意味著上次呼叫時的因數剛好將其整除盡,算作一種情況返回1。
#includeusing namespace std;
int count(int a, int b)
int main()
}
2749 分解因數
2749 分解因數 總時間限制 1000ms 記憶體限制 65536kb 描述給出乙個正整數a,要求分解成若干個正整數的乘積,即a a1 a2 a3 an,並且1 a1 a2 a3 an,問這樣的分解的種數有多少。注意到a a也是一種分解。輸入第1行是測試資料的組數n,後面跟著n行輸入。每組測試資料...
2749 分解因數
description 給出乙個正整數a,要求分解成若干個正整數的乘積,即a a1 a2 a3 an,並且1 a1 a2 a3 an,問這樣的分解的種數有多少。注意到a a也是一種分解。input 第1行是測試資料的組數n,後面跟著n行輸入。每組測試資料佔1行,包括乙個正整數a 1 a 32768 ...
百練 2749 分解因數
原題oj鏈結 給出乙個正整數a,要求分解成若干個正整數的乘積,即a a1 a2 a3 an,並且1 a1 a2 a3 an,問這樣的分解的種數有多少。注意到a a也是一種分解。第1行是測試資料的組數n,後面跟著n行輸入。每組測試資料佔1行,包括乙個正整數a 1 a 32768 n行,每行輸出對應乙個...