Programmer programming Art: Chapter 6 solving affinity numbers within 5 million

Source: Internet
Author: User

Chapter 6 affinity number problem -- solving the affinity number within 5 million

Author: shangshanruoshui, July, And yansha.
Source:Http://blog.csdn.net/v_JULY_v .

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 sum of the two, then these two numbers constitute a pair of "affinity numbers" (for more information about affinity numbers, refer to this:Http://t.cn/hesH09).

Solution:
After learning about affinity, let's take a step to solve the problem above (most of the content below comes from the original saying of water. At the same time, shuige has a saying,"Before you really understand this example, you do not deserve to understand the data structure andAlgorithm").

    1. 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.
    2. 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.
    3. 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 pre-processing array is logn (harmonic series) * n, and the time complexity of the scanning 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:

// Solve the affinity number problem </P> <p> // The first for and second for loops are logn (harmonic series) x n traversal, the third for loop scans O (n ). <Br/> // The total time complexity is O (n * logn) + O (n) = O (N * logn) (where logn is the harmonic level ). </P> <p> // description of the harmonic series in the first for and second for searches: <br/> // For example, add 2 to the multiple of 2, so it should be n/2 times, 3 plus 3 should be n/3 times ,... <br/> // n * (1 + 1/2 + 1/3 + 1/4 +... 1/(n/2) = N * (harmonic series) = N * logn. </P> <p> // copyright @ Shang shanruoshui <br/> // July, updated, 2011.05.24. <Br/> # include <stdio. h> </P> <p> int sum [5000010]; // prevents cross-border attacks </P> <p> int main () <br/>{< br/> int I, j; <br/> for (I = 0; I <= 5000000; I ++) <br/> sum [I] = 1; // 1 is the true factor of all numbers, so all are set to 1 </P> <p> for (I = 2; I + I <= 5000000; I ++) // preprocessing. The preprocessing is logn (harmonic level) * n. <Br/> // @ litaoye: harmonic series: 1/2 + 1/3 + 1/4 ...... and is approximately Ln (N), <br/> // Therefore O (N * (1/2 + 1/3 + 1/4 ......)) = O (N * ln (N) = O (N * log (n )). <Br/>{< br/> // The maximum true factor below 5000000 is not more than half of it <br/> J = I + I; // because of the true factor, so it cannot be regarded as itself, so it starts from 2 times <br/> while (j <= 5000000) <br/>{< br/> // Add I to the position where all I multiples <br/> sum [J] + = I; <br/> J + = I; <br/>}</P> <p> for (I = 220; I <= 5000000; I ++) // scan, O (n ). <Br/>{< br/> // One traversal, because the minimum values are 220 and 284, <br/> If (sum [I]> I & sum [I] <= 220 & sum [sum [I]] = I) <br/> {<br/> // deduplication, not out-of-bounds, compatible <br/> printf ("% d \ n", I, sum [I]); <br/>}< br/> return 0; <br/>}

Running result:

@ Shang shanruoshui:

1. What you may understand is not very clear. We create an array of 500 000, starting from 1 to 2 000, and add I to the position where each subscript is a multiple of I, so what do we get after the loop ends? It is an array similar to estola's prime number (of course, there is a real affinity number in it), and then you can easily find all the affinity numbers by just one traversal. Time complexity, linear.

2. We can clearly find that the ing of continuous data can be replaced by the characteristics of the array structure itself to save space. This is the art of data structure. In the backtracking of large-scale continuous data, we can convert it into a Recursive Generation Method and reverse thinking operation, which is the art of algorithms.

3. the smartest person to use the simplest things is clearer than the person who solves complicated problems with complicated methods.

Section 3,ProgramConstruction and interpretation
Let me explain the principle of the above program in detail. OK. For example, if we want to calculate the number of affinity within 10, the solution is as follows:

Because the true factor of all numbers includes 1, first set 1 at the bottom of each number.

  1. take I = 2, 3, 4, 5 (I <= 10/2), where J corresponds to J = (4, 6, 8, 10 ), (6, 9), (8), (10) the location of each number.
  2. Based on the Position found by J, add the true factors I (I = 2, 3, 4, and 5) under the numbers referred to by J ).
    the entire process, as shown in (for example, sum [6] = 1 + 2 + 3 = 6, sum [10] = 1 + 2 + 5 = 8 .):
    1 2 3 4 5 6 7 8 9 10
    1 1 1 1 1 1 1 1 1
    2 2 2 2
    3
    4
    5
  3. And then traverse I from 220 to 5000000. After I traverse each number,
    Add each real factor under the number corresponding to I to get a sum [I]. If sum [I] = a certain I 'and sum [I'] = I,
    The two numbers I and I are a pair of affinity numbers.
  4. I = 2; sum [4] + = 2, sum [6] + = 2, sum [8] + = 2, sum [10] + = 2, sum [12] + = 2...
    I = 3, sum [6] + = 3, sum [9] + = 3...
    ......
  5. When I = 220, sum [220] = 284, when I = 284, sum [284] = 220; that is, sum [220] = sum [sum [284] = 284,
    It is concluded that 220 and 284 are a pair of affinity numbers. Therefore, the final output is 220, 284 ,...

Special thanks

Litaoye will post on this matter. If you are interested, refer:Http://topic.csdn.net/u/20110526/21/129c2235-1f44-42e9-a55f-878920c21e19.html. At the same time, anyone who has any questions about this affinity can reply to the above post.

// Solve the affinity number problem <br/> // copyright @ litaoye <br/> // July, Hu Bin, updated, 2011.05.26. <Br/> using system; <br/> using system. collections. generic; </P> <p> namespace csharptest <br/> {<br/> class Program <br/>{< br/> Public static void main () <br/>{< br/> int max = 5000000; <br/> datetime start = datetime. now; <br/> int [] counter = createcounter (max); </P> <p> for (INT I = 0; I <counter. length; I ++) <br/>{< br/> int num = counter [I]-I; <br/> // If (Num <counter. length & num> I & Counter [NU M] = counter [I]) <br/> // console. writeline ("{0} {1}", I, num); <br/>}< br/> console. writeline (datetime. now-Start ). totalseconds); </P> <p> console. readkey (); <br/>}</P> <p> static int [] createcounter (int n) <br/>{< br/> List <int> primes = new list <int> (); <br/> int [] counter = new int [n + 1]; <br/> counter [1] = 1; </P> <p> for (INT I = 2; I <= N; I ++) <br/>{< br/> If (counter [I] = 0) <br/>{< br/> Counter [I] = I + 1; <br/> primes. add (I); <br/>}</P> <p> for (Int J = 0; j <primes. count; j ++) <br/>{< br/> If (primes [J] * I> N) <br/> break; </P> <p> if (I % primes [J] = 0) <br/>{< br/> int K = I; <br/> int L = primes [J] * primes [J]; </P> <p> while (K % primes [J] = 0) <br/> {<br/> L * = primes [J]; <br/> K/= primes [J]; <br/>}</P> <p> counter [primes [J] * I] = counter [k] * (L-1)/(primes [J]- 1); <br/> break; <br/>}< br/> else <br/> counter [primes [J] * I] = counter [I] * (primes [J] + 1 ); <br/>}</P> <p> return counter; <br/>}</P> <p>/* <br/> Test Result: <br/> 0.484375 <br/> 0.484375 <br/> 0.46875 <br/> unit: second. <Br/> */

This chapter is complete.

3.3 continued. Calculate the K-small (large) element in the given range.
Chapter 9 catch-up with gossip linked lists
Chapter 10: how to sort disk files with 10 ^ 7 data volumes

Interview question Collection order

    1. Thirteen classical algorithm research series + appendix, red and black tree series (the most classic red and black tree tutorial in history in China), total 20 + 6 = 26 articlesArticleIt took nearly a week to create a PDF document with a directory and tags. It took 346 pages (enough for a book) and was completed with the help of the bright moon.
    2. If you want to, send a self-think better interview questions (C, C ++, data structure, algorithm, smart questions, digital logic or operation questions) to my mailbox: zhoulei0907@yahoo.cn, you can. The PDF file will be sent within three days after I receive it. July and 20110.5.24. This statement is permanently valid.

All rights reserved. I have all rights reserved and copyright to all content in this blog. To be reproduced, please indicate the source in the form of a link.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.