I. Description of the problem
Arbitrarily given a positive integer n, a minimum positive integer M (m>1) is obtained so that the N*m decimal form contains only 1 and 0.
For example N=99,m=1 122 334 455 667 789, n*m=111 111 111 111 111 111;
M is the number that meets the criteria when n=99
Ii. Thinking of solving problems
Consider turning the problem into: finding the smallest positive integer that contains only 0 and 1 that can be divisible by N. It can be seen that this is equivalent to the original problem.
So is it necessary to traverse all the numbers that comprise 0 and 1 from small to large? In this case, if the number is looking for k, you need to search the number of 2k-1 to get results.
The method used here is to preserve the remainder information of the%n in the calculation and avoid unnecessary computations. More formalized discourse:
If all K-bit (X) decimal numbers have been traversed, and the minimum number of k+1 digits of t=10k (10) is also searched, all k+1 numbers (Y) are now examined. The
More Wonderful content: http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/
Y=x+t (that is, the number of all K-Systems +10k), if we divide the space by the X by%n, and the X is decomposed into the equivalence class of the remainder (0~n-1), then the search Y is only required to take the representative element in x to modulo, thus reducing the search time from 2K to N. The smallest element is saved in each equivalence class in a specific implementation.
Third, code implementation
#include <iostream> #include <vector> #include <string> #define N 100213 using namespace std;
Vector<vector<int> >BigIntVec;
void Printnum (const vector<int>& TV) {//cout<< "print" <<endl;
int Maxindex=tv.back ();
String Numstr= "";
for (int i=0;i<maxindex+1;i++) {numstr+= "0";
for (int i=0;i<tv.size (); i++) {numstr[maxindex-tv[i]]= ' 1 ';
cout<< "The minimum number of eligible numbers found is:" <<endl;
for (int i=numstr.size () -1;i>=0;i--) {cout<<numstr[i];
} cout<<endl;
} void FindNum () {for (int i=0;i<n;i++) {vector<int>tt;
Bigintvec.push_back (TT);
} bigintvec[1].push_back (0);
int noupdate=0; for (int i=1,j=10%n;;;
i++,j= (j*10)%N) {bool Flag=false;
if (Bigintvec[j].size () ==0) {bigintvec[j].push_back (i);
Flag=true;
for (int k=0;k<n;k++) { if (Bigintvec[k].size () >0&&i>bigintvec[k].back ()) {int t= (K+J)
%N;
if (Bigintvec[t].size () ==0) {for (int tt=0;tt<bigintvec[k].size (); tt++) {
Bigintvec[t].push_back (Bigintvec[k][tt]);
} bigintvec[t].push_back (i);
Flag=true;
}} if (Flag==false) {noupdate++;
}else{noupdate=0; } if (Bigintvec[0].size () >0| |
Noupdate==n) {break;
} if (Bigintvec[0].size () >0) {printnum (bigintvec[0]);
}else{cout<< "does not find a qualifying number" <<endl;
int main () {findnum ()};
System ("pause");
return 0; }
Note: Because the integer involved in this issue can be very large and cannot be represented by a built-in type int or long, vector is used to simulate integers in the program. Because the number of searches is only 1, 2 kinds of numbers, in order to save space, each integer is represented by vector<int>, and vector each element holds 1 occurrences. For example, the number 100101, vector<int> is expressed as {0,2,5}, where 1 of the positions are No. 0, 2, 5 digits respectively.
Iv. output of the program (Input N: 100213):