Original problem Description:
For a given positive integer n, calculate how many different decomposition types n have.
For example, when n=12, there are 8 different types of decomposition:
12=12,
12=6X2,
12=4X3,
12=3X4,
12=3X2X2,
12=2x6,
12=2X3X2,
12=2x2x3
For each factor of n recursive search, the code is as follows:
void solve (int n)
{
if (n==1)
total++;
else for
(int i=2; i<=n; i++)
if (n%i==0)
solve (n/i);
}
Extension question one: can output a variety of specific decomposition expressions.
Idea: You can set a stack, if it is a factor, then the factor is pressed into the stack, recursive to the factor of 1 o'clock decomposition complete, the entire stack of elements output. POPs the element at the top of the stack at the end of a recursive (vector container simulation stack in this case). The code is as follows:
void solve (int n)
{
if (n = = 1)
{
total++;
Print_vector (Ivec);//The element in the output stack
}
else for
(int i = 2; I <= n; i++)
if (n% i = = 0)
{
///If I is a factor of N, The i is pressed into the stack
ivec.push_back (i);
Solve (n/i);
Ivec.pop_back ();//Out Stack
}
}
Extension question two: can output a non-repeating decomposition expression. The first way of thinking: After many experiments found that if the recursive end, the elements in the simulation stack is unordered, then this decomposition must be repeated. Take 12 as an example, there are 3 kinds of cases: 2x2x3, 2x3x2, 3x2x2, the latter two reasons are repeated, because they are disordered, so, on the basis of the first problem, only need to determine before the output of the simulation stack elements are orderly, if the order, the output. The code is as follows:
void solve (int n)
{
if (n = = 1)
{
total++;
if (Isordervector (IVEC))//Only in order, output
print_vector (IVEC);//elements in the output stack
}
else for
(int i = 2; I <= n; i++)
if (n% i = = 0)
{
//If I is a factor of n, then I will be pressed into the stack
ivec.push_back (i);
Solve (n/i);
Ivec.pop_back ();//Out Stack
}
}
The code that determines whether the simulation stack is ordered is as follows:
BOOL Isordervector (vector<int> & Ivec)
{
assert (ivec.size () > 0);
for (Vector<int>::iterator i = ivec.begin () + 1; I! = Ivec.end (); i++)
if (*i < * (i-1))
return false;
return true;
}
Further optimization of problem two: in fact slove () function inner Loop I do not need to loop to n, only need to loop to sqrt (n) can, of course, needs to be added to the missing case: When I is n, the code is as follows:
void solve (int n)
{
...
else
{
for (int i = 2; I <= sqrt (n); i++)
{
if (n% i = = 0)
{
//If I is a factor of n, then I is pressed into the stack
Ivec . push_back (i);
Solve (n/i);
Ivec.pop_back ();//Out Stack
}
}
{
ivec.push_back (n);
Slove (1);
Ivec.pop_back ();}}}
The second way of thinking [Zhang students provide]: since in order to maintain the sequence of elements in the simulation stack, that every time I into the stack before the stack with the top element to compare, if I is greater than the top of the stack, then not into the stack, this method is more concise, the code is as follows:
void solve (int n)
{
if (n = = 1)
{
total++;
Print_vector (Ivec);//The element in the output stack
}
else for
(int i = 2; I <= n; i++)
if (n% i = = 0)
{
//If the stack is not empty and I ratio The top element of the stack is small, indicating
//re-pressure stack has no meaning, the direct end of the cycle.
if ((ivec.size () > 0) && i < Ivec[ivec.size ()-1])
continue;
If I is a factor of n, then I is pressed into the stack
ivec.push_back (i);
Solve (n/i);
Ivec.pop_back ();//Out Stack
}
}
Reference: Beijing University Rochen algorithm design and Analysis Chapter III courseware