1. Brief Introduction
Given a positive integer N, evaluate a minimum positive integer M (M> 1) so that the decimal representation of N * M contains only 1 and 0.
For example, when N = 99, M = 1 122 334 455 667 789, N * M = 111 111 111 111 111 111.
2. Ideas
In fact, one of the two ideas is to traverse N and M to determine whether N * M meets the conditions. The other is to traverse N to determine whether the values meet the conditions and whether they can be divisible by N. According to the sample data, when N = 99, the complexity of the first method is: M = 1 122 334 455 667 789, the complexity of the second method is 2 ^ 15 = 32*1024. That is to say, the number composed of 0 and 1 is actually very sparse, and traversing from here is faster. This is similar to the beauty of programming. The telephone number in section 3.2 corresponds to an English word, that is, the combination of telephone numbers is huge, but the English word is very limited.
In the process of traversing a value with only 0 or only 1, assuming that the target result has k digits, you must traverse a maximum of 2 ^ k digits, which can be further simplified, for example, 123,123 = 100 + 23 means 123% N = 100% N + 23% N. Assuming that the number of single digits and ten digits have been calculated, the possible remainder of single digits and ten digits can be maintained. For the remainder of hundreds of digits, it must be within the range of (remainder calculated before 100% N +) % N. If a new remainder is generated, update the remainder. When saving the remainder, record the minimum value of the remainder. Assuming that the target result has k bits, the computational complexity is k (N-1 ).
3. Code
# Include <iostream>
Using namespace std;
Int find_M (int N ){
// Boundary Condition
If (N = 1)
Return 1;
// Initialize the remainder Array
Int * A = new int [N]; // records the existing remainder. A [I] indicates that the remainder of N is the minimum value that meets the condition of I.
Int * B = new int [N]; // records the remainder of the update.
Memset (A,-1, N * sizeof (int ));
A [1] = 1;
// Search process
Int factor = 10;
Bool not_found = true;
While (not_found ){
Memset (B,-1, N * sizeof (int ));
Int x = factor % N; // the remainder of N for a high value
// When the high value is + 0
If (A [x] =-1 ){
B [x] = factor;
If (x = 0)
Break;
}
// When the high value + the low positive integer is used
For (int I = 1; I <N; I ++) {// traverse each possible Remainder
If (A [I] =-1)
Continue;
Int new_x = (x + I) % N; // The calculated remainder.
If (A [new_x] =-1 & B [new_x] =-1) {// if it is A new remainder, save
B [new_x] = factor + A [I];
If (new_x = 0) {// The New remainder just found is 0
Not_found = false;
Break;
} // If
} // If
} //
Factor * = 10;
For (int I = 0; I <N; I ++ ){
If (A [I] =-1 & B [I]! =-1 ){
A [I] = B [I];
}
}
} // While
Int result = B [0];
Delete [];
Delete [] B;
Return result;
}
Int main (){
Int N;
While (true ){
Cout <"N :";
Cin> N;
If (N <1)
Break;
Cout <"M:" <find_M (N)/N <endl;
Cout <"positive integer:" <find_M (N)/N * N <endl;
}
System ("pause ");
Return 0;
}
Note: Two remainder arrays are used in the code to calculate all the new remainder values at the High Level and save them together. If one calculation is performed, the high level will be affected by itself. For example, if 101 bits are currently calculated, if 100 is saved in a [7], and is calculated to a [2], then when + A [7] is calculated, in fact, the calculated value is 100 + 101 = 201, which is an invalid character. Therefore, each calculated value must be saved at one time. In addition, it should be noted that 0 is processed separately each time, that is, 10 + 0,100 + 0.
Result output:
4. Code of beauty in programming
The code above is written based on the basic idea, and then the code in the book. It is found that it is still the essence of the book. The code in the book is better in the following aspects: first, if n * m numbers are large and INT values cannot be stored, the book uses a queue to record the position of 1 in the value. For example, for 1, record 0. For 1110011, record 01456. Second, if there is no new remainder in each cyclic section, the m that meets the condition will never be found. How can this be proved. In addition, the code in the book also considers the high + 0 and high + low, and the high one-time storage problem, but the code in the book is more elegant.
5. Reference
The beauty of programming. In section 2.8, find the qualified integer.