The beauty of programming: 2.8 -- search for qualified Integers

Source: Internet
Author: User

Problem:
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.

Solution:
There is no direct mathematical method to help us directly obtain the M value, so we can only search. Because product N * M has obvious features relative to M, the search space is much smaller, so we search product N * M. If the N * M result has K digits, We need to cycle 2 ^ K times. We found that K results can easily exceed 40, so the running time is still quite long.
The coequal operation has an equivalence relationship. mod N = I (0 <= I <N) Forms N equivalence classes and divides positive integer sets. For each equivalence class, we only need to judge whether the smallest element plus 10 ^ K can be divisible by N, so that the search space is reduced from 2 ^ K times to (K-1) * N step, the value of N is generally much smaller than the value of M. But it requires O (N) space complexity.
We can prove that for any N, there must be M, so that the product of N * M in decimal format is only 0 and 1. The proof process can be seen in the fact that both M and N * M have a large number of digits, so we use a large integer to represent M and N * M. Because N is a big integer, N cannot be a big integer, that is, the value of N should be less than 1 million.
[Cpp]
# Include <iostream>
# Include <cstring>
Using namespace std;
 
// Big Integer type
# Define MAXLEN 100
Struct HP {int len, s [MAXLEN];};
 
Void PrintHP (const HP & x)
{
For (int I = x. len; I> = 1; I --)
Cout <x. s [I];
}
 
// Convert the string to a large integer
Void Str2HP (const char * s, HP & x)
{
X. len = strlen (s );
For (int I = 1; I <= x. len; I ++)
X. s [I] = s [x. len-I]-'0 ';
If (x. len = 0)
{
X. len = 1;
X. s [1] = 0;
}
}
 
// Addition of large Integers
Void Plus (const HP a, const HP B, HP & c)
{
Int I; c. s [1] = 0;
// The addition operation of big integers a and B and the carry operation of Result c
For (I = 1; I <= a. len | I <= B. len | c. s [I]; I ++)
{
If (I <= a. len) c. s [I] + = a. s [I];
If (I <= B. len) c. s [I] + = B. s [I];
C. s [I + 1] = c. s [I]/10; c. s [I] % = 10;
}
// Exit the loop because c. s [I] = 0.
C. len = I-1;
If (c. len = 0) c. len = 1;
}
 
// Subtraction of large Integers
Void Subtract (const HP a, const HP B, HP & c)
{
Int I, j;
For (I = 1, j = 0; I <= a. len; I ++)
{
// J indicates whether to borrow a bid from a high position
C. s [I] = a. s [I]-j;
If (I <= B. len) c. s [I]-= B. s [I];
If (c. s [I] <0)
{
// Borrow from the high bid and add 10
J = 1;
C. s [I] + = 10;
}
Else j = 0;
}
C. len = a. len;
While (c. len> 1 &&! C. s [c. len]) c. len --;
}
 
// Compare large Integers
Int HPCompare (const HP & x, const HP & y)
{
If (x. len> y. len) return 1;
If (x. len <y. len) return-1;
Int I = x. len;
While (I> 1 & (x. s [I] = y. s [I]) I --;
Return x. s [I]-y. s [I];
}
 
// Multiplication of large Integers
Void Multi (const HP a, const HP B, HP & c)
{
Int I, j;
// Assign an initial value to the multiplication result to facilitate subsequent + = operations
C. len = a. len + B. len;
For (I = 1; I <= c. len; I ++) c. s [I] = 0;
For (I = 1; I <= a. len; I ++)
For (j = 1; j <= B. len; j ++)
C. s [I + J-1] + = a. s [I] * B. s [j];
// Carry the operation result
For (I = 1; I <c. len; I ++) {c. s [I + 1] + = c. s [I]/10; c. s [I] % = 10 ;}
// Carry the highest bit
While (c. s [I]) {c. s [I + 1] = c. s [I]/10; c. s [I] % = 10; I ++ ;}
// Ensure that the maximum bit is not 0
While (I> 1 &&! C. s [I]) I --;
C. len = I;
}
 
// Division of large Integers
Void Divide (const HP a, const HP B, HP & c, HP & d)
{
Int I, j;
// Use the remainder d to store the first I-bit data of divisor a, and subtract the divisor B multiple times to obtain the operator c
D. len = 1; d. s [1] = 0;
For (I = a. len; I> 0; I --)
{
If (! (D. len = 1 & d. s [1] = 0 ))
{
// I does not move one bit, and the remainder d is also shifted.
For (j = d. len; j> 0; j --)
D. s [j + 1] = d. s [j];
D. len ++;
}
D. s [1] = a. s [I];
C. s [I] = 0;
// The subtraction operation can be performed only when the remainder d is greater than the divisor B.
While (j = HPCompare (d, B)> = 0)
{
Subtract (d, B, d );
C. s [I] ++;
If (j = 0) break;
}
}
C. len = a. len;
While (c. len> 1 & c. s [c. len] = 0)
C. len --;
}
// Shifts decimal places to the right
Void RightShift (HP & x, int k)
{
For (int I = 1; I <= x. len-k; I ++)
X. s [I] = x. s [I + k];
X. len-= k;
If (x. len <= 0)
{
X. len = 1;
X. s [1] = 0;
}
}
// Decimal left shift
Void LeftShift (HP & x, int k)
{
Int I;
For (I = x. len; I> = 1; I --)
X. s [I + k] = x. s [I];
For (I = k; I> = 1; I --)
X. s [I] = 0;
X. len + = k;
}
 
# Define MAXREM 1000000
HP rem [MAXREM];
 
Int main ()
{
Int I, j, k, N;
Char str [MAXREM];
HP one, tmp;
One. len = 1; one. s [1] = 1;
While (cin> str)
{
N = atoi (str );
If (N> MAXREM)
{
Printf ("ERROR: N (% d) is too large", N );
Continue;
}
// Clear the remainder information array
For (I = 0; I <N; I ++)
Rem [I]. len = 0;
// Initialize the unique single digit 1
Rem [1] = one;
// I indicates the I bit of N * M found, and j indicates (10 ^ I) % N
For (I = 1, j = 10% N; rem [0]. len = 0; I ++, j = (j * 10) % N)
{
// Tmp indicates a large integer of 10 ^ N
Tmp = one;
LeftShift (tmp, I );
// If the array does not have the same number as tmp
If (rem [j]. len = 0)
Rem [j] = tmp;
For (k = 1; k <N; k ++)
{
// Traverses the remainder information array. If a new remainder is generated
Int u = (j + k) % N;
// To prevent the newly added 10 ^ N from being calculated, add the condition rem [k]. len <= I
If (rem [k]. len & rem [k]. len <= I
& Rem [u]. len = 0)
Plus (tmp, rem [k], rem [u]);
If (u = 0)
Break;
}
} Www.2cto.com
Str2HP (str, tmp );
Cout <"N * M :";
PrintHP (rem [0]);
HP d;
Divide (rem [0], tmp, tmp, d );
Cout <endl <"M :";
PrintHP (tmp );
Cout <endl;
}
}
Author: linyunzju
 

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.