Reprinted please indicate the source: Thank you
Http://user.qzone.qq.com/289065406/blog/1303946967
General question:
Returns an integer N, (1 <=n <= 200 ). To obtain any of its multiples, m must be composed of '0' or '1' in decimal format.
Solution:
First, brute-force enumeration is certainly impossible. If you want to avoid timeout in 1000 ms, It is difficult. In addition, enumeration must solve the problem of large numbers ..
If it weren't for people to search for this question, they wouldn't think of BFS...
Solution: BFS + same modulus Theorem
Don't talk nonsense.
First, let's talk about the simple method of searching without pruning:
Take n = 6 as an example.
First, the decimal number. The first digit (highest digit) must not be 0, that is, the highest digit must be 1.
Set "01 decimal multiple" of 6 to K, then K % 6 = 0
Now we need to use BFs to calculate the K value.
1. First search for the highest bit of K. The highest bit must be 1. Then k = 1, but 1% 6 = 1! = 0
Therefore, k = 1 is not required,Storage remainder 1
2. Search for the next digit. The next digit may be 0, that is, K * 10 + 0. k = 10, then K % 6 = 4
It may be 1, that is, K * 10 + 1. At this time, K = 11, then K % 6 = 5
Since the remainder is not 0, K = 10 and K = 11 are not required
3. Continue searching for the third digit. There are four possibilities:
For k = 10, the next digit may be 0, that is, K * 10 + 0. k = 100, then K % 6 = 4
The next digit may be 1, that is, K * 10 + 1. k = 101, then K % 6 = 5
For k = 11, the next digit may be 0, that is, K * 10 + 0. k = 110, then K % 6 = 2
The next digit may be 1, that is, K * 10 + 1. k = 111, then K % 6 = 3
Since the remainder is not 0, that is, K = 100, K = 101, K = 110, K = 111 are not required
4. Continue searching for the fourth digit. There are eight possibilities:
For k = 100, the next digit may be 0, that is, K * 10 + 0. k = 1000, then K % 6 = 4
The next digit may be 1, that is, K * 10 + 1. k = 1001, then K % 6 = 5
For k = 101, the next digit may be 0, that is, K * 10 + 0. k = 1010, then K % 6 = 2
The next digit may be 1, that is, K * 10 + 1. k = 1011, then K % 6 = 3
For k = 110, the next digit may be 0, that is, K * 10 + 0. k = 1100, then K % 6 = 2
The next digit may be 1, that is, K * 10 + 1. k = 1101, then K % 6 = 3
For k = 111, the next digit may be 0, that is, K * 10 + 0. k = 1110, then K % 6 = 0
The next digit may be 1, that is, K * 10 + 1. k = 1111, then K % 6 = 1
When K = 1110, K % 6 = 0, that is, 1110 is the desired multiple.
From the above deduction, it is not difficult to find that BFS is used to search for the current digit (except the highest digit is fixed as 1), because each digit has only 0 or 1 options, in other words, it is a dual-portal BFS
The difficulty of this question lies in the processing after the search: processing the remainder, processing the large number, and the relationship between the remainder and the desired multiple
Next, let's talk about how to deal with the big number problem and how to pruning:
First, let's briefly review the simple search method:
N = 6
1% 6 = 1 (k = 1)
{
(1*10 + 0) % 6 = 4 (k = 10)
{
(10*10 + 0) % 6 = 4 (k = 100)
{
(100*10 + 0) % 6 = 4 (k = 1000)
(100*10 + 1) % 6 = 5 (k = 1001)
}
(10*10 + 1) % 6 = 5 (k = 101)
{
(101*10 + 0) % 6 = 2 (k = 1010)
(101*10 + 1) % 6 = 3 (k = 1011)
}
}
(1*10 + 1) % 6 = 5 (k = 11)
{
(11*10 + 0) % 6 = 2 (k = 110)
{
(110*10 + 0) % 6 = 2 (k = 1100)
(110*10 + 1) % 6 = 3 (k = 1101)
}
(11*10 + 1) % 6 = 3 (k = 111)
{
(111*10 + 0) % 6 = 0 (k = 1110) Solution
(111*10 + 1) % 6 = 1 (k = 1111) due to previous solutions, This remainder is not stored
}
}
}
From the above, we can see the sequence of the remainder (layer-by-layer storage ):
Use the array mod [] to store the remainder, where mod [0] is not used, starting with Mod [1 ].
The remainder in mod is:1 4 5 4 5 2 4 5 2 3 2 3 014 in total
That is, before we get the remainder 0, we performed 14 steps * 10. When the N value is large enough, it is very easy to see that K is a large number (in fact, I have done statistics, N within 200, there are 18 N corresponding to the K value is a large number
It is wise to store K with Int.
In order to deal with all the situations, we naturally think that we should use int [] to store every bit of K?
But since K is a 01 sequence, can we* 10. Obtain K for each bit.ConvertThe operation of mod 2 obtains each bit of K (0 or 1)
What about it?
The answer is yes.
First, we useSame modulus TheoremOptimize the method for getting the remainder
(A * B) % N = (a % N * B % N) % N
(A + B) % N = (a % N + B % N) % N
Take the preceding formula as an example.
Previous step (11*10 + 1) % 6 = 2 that is, K = 110, K % 6 = 2
Current step (110*10 + 1) % 6 = 2
Theorem of same Modulus(110*10 + 1) % 6 = (110*10) % 6 + 1% 6) % 6 = (110% 6 * 10% 6) % 6 + 1) % 6
It is not difficult to find that the underline part 110% 6 is equal to (11*10 + 0) % 6 = 2
So the current step (110*10 + 1) % 6 can be changed to (2*10 + 1) % 6 = 2
Obviously, K = 110 is equivalent to k = 2.
Out-of-the-boxThe remainder obtained by the previous step.ReplaceK value of the current step
While N is in the range of 200, the remainder value cannot exceed three digits, which solves the problem.Big Data problems
Through this processing method, we only need to store a remainder array mod [] In BFs, We can get mod [I] Through mod [I-1], the operation time is greatly reduced until mod [I] = 0.
As mentioned above, when n = 6, the remainder operation is performed 14 times. Correspondingly, the BFS * 10 operation is also performed 14 times.
After I = 14, we can see that I % 2 is exactly the second digit in multiples of 6.
I/2 and then I % 2, which is exactly the next low digit in multiples of 6...
Loop through this operation, until I = 0, you can get a 01 multiple of 6 (A 01 Queue), the inverted output is what you want
This completes the transition from * 10 to % 2.
Because the N value is limited, it is only an integer between 1 and 200. Therefore, you can also use a table. After obtaining the result through the above method, set 1 ~ Print it out in multiples of 200, re-create a program, and directly create a table.
However, table creation is not much faster than the method described above.
// Memory time // 2236 K 32 Ms # include <iostream> using namespace STD; int mod [524286]; // Save the remainder of mod n each time. // because the remainder sequence of 198 is the longest, // It is verified by repeated binary verification, 436905 is the minimum space that can store more than 198 of the number of sequences // But poj must have passed the out-of-bounds test... 524286 is the minimum limit of the AC. Otherwise, reint main (int I) {int N; while (CIN> N) {If (! N) break; mod [1] = 1% N; // initialization, the maximum number of N multiples must be 1for (I = 2; mod [I-1]! = 0; I ++) // use the same modulus theorem, the remainder mod [I/2] in the previous step gets the remainder mod [I] mod [I] = (mod [I/2] * 10 + I % 2) % N; // mod [I/2] * 10 + I % 2 simulates the BFS double-entry search // when I is an even number, + 0, that is, the current digit is 0. If the value is an odd number, + 1 indicates that the current digit is 1i --; int PM = 0; while (I) {mod [PM ++] = I % 2; // convert * 10 to % 2. Calculate the number I/= 2;} while (PM) cout <mod [-- PM]; // output cout in reverse order <Endl;} return 0 ;}