Prelude
In this chapter, apart from retaining the original string, array, and other interview questions, we will consciously cut off some interview questions about small and clever numbers, focusing on the clever ideas ", and "wonderful ". This chapter describes the key words of affinity number, "5 million" and "linear complexity ".
Section 1 affinity
Description:
Calculate the number of all affinity values less than 5 million
If the sum of all true factors of two numbers a and B and a is equal to B, and the sum of all true factors of B is equal to a, a and B are a pair of affinity numbers.
For example 220 and 2924 and.
Analysis:
First, we need to clarify what is affinity?
The affinity number problem was first discovered and studied by the bildagos School. When studying the law of numbers, they found two numbers with the following characteristics:
The true factors of 220 are: 1, 2, 4, 5, 10, 11, 20, 22, 44, 55, and 110;
The true factors of 284 are: 1, 2, 4, 71, and 142.
And the two numbers are exactly the sum of the true factors of the other side (sum [I] indicates the sum of the true factors of the number I), that is
220 = 1 + 2 + 4 + 71 + 142 = sum [284],
284 = 1 + 2 + 4 + 5 + 10 + 11 + 20 + 22 + 44 + 55 + 110 = sum [220].
Sum [284] = 284, and sum [220] = 220, that is, sum [220] = sum [284] = sum [220] = sum [sum [284] = 284.
Is there any clue?
As shown above, considering that 1 is the factor of each integer, all factors out of the integer itself are called the "true factor" of this number ". If the sum of two integers, each of which is exactly the same as the other, then these two numbers constitute a pair of "affinity numbers"
Solution:
After learning about affinity data, let's take a step-by-step approach to solving the problem raised above (most of the content below comes from the original saying of water. At the same time, shuige has an original saying, "Before you really understand this example, you don't deserve to say that you understand data structures and algorithms ").
What is the first thought after seeing this question? Simulated search + pruning? Backtracking? What is the time complexity? Where bn is the pseudo affinity of an, that is, what is the sum of the true factors of an bn? At least 10 ^ 13 (@ iicup: N ^ 1.5 for 5*10 ^ 6, the number of times is roughly 10 ^ 10 rather than 10 ^ 13. For computers that perform tens of millions of operations per second, it can be completed in more than 1000 days, that is, within three years (iicup computing: 10 ^ 13/10 ^ 7 = 1000000 (seconds) about 278 hours .). If you are optimizing based on this base, you cannot get results within one day.
A good algorithm should solve this problem within half an hour. Of course there are many such algorithms. The time-saving method is to generate an adjoint array, that is, to change the space for time. However, the space cost is too large because of the large data size.
In the later algorithm, the companion array is still used, but because of the special nature of the question, it is only convenient and clever to use the subscript as the companion array to save time. At the same time, we will replace the Backtracking idea with the recursive idea (the time complexity of the preprocessing array is logN (harmonic series) * N, and the time complexity of scanning the array is linear O (N ). Therefore, the total time complexity is O (N * logN + N) (where logN is the harmonic level )).
Section 2 linear traversal of adjoint Arrays
Based on the above 3rd ideas, write the following code:
View plaincopy to clipboardprint?
// Solve the affinity Number Problem
// The first for and second for loops are logn (harmonic series) x N traversal, and the third for loop scans O (N ).
// Therefore, the total time complexity is O (n * logn) + O (n) = O (N * logN) (where logN is the harmonic level ).
// Description of the harmonic series in the first for and second for searches:
// For example, if you add 2 to a multiple of 2, it should be n/2, and 3 to a multiple of 3 should be n/3 ,...
// It is actually n * (1 + 1/2 + 1/3 + 1/4 +... 1/(n/2) = n * (harmonic series) = n * logn.
// Copyright @ Shang shanruoshui
// July, updated, 2011.05.24.
# Include <stdio. h>
Int sum [5000010]; // prevents cross-border attacks
Int main ()
{
Int I, j;
For (I = 0; I <= 5000000; I ++)
Sum [I] = 1; // 1 is the true factor of all numbers, so all are set to 1.
For (I = 2; I + I <= 5000000; I ++) // preprocessing. The preprocessing is logN (harmonic level) * N.
// @ Litaoye: The sum of the harmonic series 1/2 + 1/3 + 1/4 ...... is approximately ln (n ),
// So O (n * (1/2 + 1/3 + 1/4 ......)) = O (n * ln (n) = O (N * log (N )).
{
// The maximum true factor below 5000000 is not more than half of it
J = I + I; // because of the true factor, it cannot be regarded as itself, so it starts from 2 times
While (j <= 5000000)
{
// Add the I
Sum [j] + = I;
J + = I;
}
}
For (I = 220; I <= 5000000; I ++) // scan, O (N ).
{
// A traversal starts from 220 because the minimum values are 284 and 220.
If (sum [I]> I & sum [I] <= 5000000 & sum [sum [I] = I)
{
// Deduplicate and not cross-border, satisfying affinity
Printf ("% d", I, sum [I]);
}
}
Return 0;
}
Running result:
@ Shang shanruoshui:
1. What you may understand is not very clear. We have created an array of 500, which is opened from 1 to 2.