POJ 1426 Find the multiple (search)

Source: Internet
Author: User


A-find the multiple time limit:1000MS Memory Limit:10000KB 64bit IO Format:%lld & %llu Submit Status Practice POJ 1426

Description Given A positive integer n, write a program to find out a nonzero multiple m of n whose decimal representation Contains only the digits 0 and 1. You may assume this n is not greater than and there are a corresponding m containing no more than decimal digits.

Input the input file may contain multiple test cases. Each line contains a value of n (1 <= n <= 200). A line containing a zero terminates the input.

Output for each value of n in the input print a line containing the corresponding value of M. The decimal representation of M must not contain more than digits. If There is multiple solutions for a given value of N, any one of the them is acceptable.

Sample Input

2
6
0

Sample Output

Ten
100100100100100100
111111111111111111


Deep Search:

2014.4.7
///poj1426

#include <iostream>
#include <cstdio>
using namespace std;

BOOL found;
int n;

void Dfs (unsigned long long a,int deep) {
    if (found)
        return;
    if (a%n = = 0) {
        found = true;
        cout<<a<<endl;
        return;
    }
    if (deep>=19)    //Use this control to jump out of conditional
        return;
    DFS (a*10,deep+1);
    DFS (a*10+1,deep+1);
}

int main ()
{
    //Freopen ("in", "R", stdin);
    Freopen ("Out", "w", stdout);

    while (Cin>>n && N) {
        found = false;
        DFS (1,0);
    }
    return 0;
}

Wide search (written by teammate Cilyb

#include <iostream>
#include <queue>
using namespace std;
Long long n, res[201];
Long long BFS (int k)
{
    Queue<long long>que;
    Que.push (1);
    while (1)
    {
        if (!) ( Que.front ()%k))
            return Que.front ();
        Que.push (Que.front () *10);
        Que.push (Que.front () *10+1);
        Que.pop ();
    }
return 0;
}
int main (void)
{for
    (int i = 1; i < 201; i++)
        res[i] = BFS (i);
    while (CIN >> n && N)
        cout << res[n] << Endl;
}

Online Big God code + Analysis


first of all, simple, non-pruning search methods:

I take n=6 as an example.

First decimal number, first digit (highest bit) must not be 0, that is, the highest bit must be 1

Set 6 "10 binary" to K, then must have k%6 = 0

Now we're going to use BFS to find K-values.

1, first search the highest bit of K, the highest bit must be 1, then k=1, but 1%6 = 1! = 0

So k=1 is not asking for the remainder of the storage 1

2, search the next one, the next one may be 0, that is k*10+0, at this time k=10, then k%6=4

May be 1, that is k*10+1, at this time k=11, then k%6=5

Because the remainder is not 0, that is, k=10 and k=11 are not asked

3, continue to search for the third place, there are four possibilities:

For k=10, the next one may be 0, or k*10+0, at this time k=100, then k%6=4

The next one may be 1, that is k*10+1, at this time k=101, then k%6=5

For k=11, the next one may be 0, or k*10+0, at this time k=110, then k%6=2

The next one may be 1, that is k*10+1, at this time k=111, then k%6=3

Since the remainder is not 0, that is, the k=100,k=101,k=110,k=111 is not a request

4, continue to search the fourth place, at this time there are eight possibilities:

For k=100, the next one may be 0, or k*10+0, at this time k=1000, then k%6=4

The next one may be 1, that is k*10+1, at this time k=1001, then k%6=5

For K=101, the next one may be 0, or k*10+0, at this time k=1010, then k%6=2

The next one may be 1, that is k*10+1, at this time k=1011, then k%6=3

For k=110, the next one may be 0, or k*10+0, at this time k=1100, then k%6=2

The next one may be 1, that is k*10+1, at this time k=1101, then k%6=3

For k=111, the next one may be 0, or k*10+0, at this time k=1110, then k%6=0

The next one may be 1, that is k*10+1, at this time k=1111, then k%6=1

When we find k=1110, k%6=0, or 1110, is the multiple we ask for.

 

from the above deduction is not difficult to find, with BFS is to search the current digit (except the highest bit fixed to 1), because each bit only 0 or 12 choice, in other words is a double inlet BFS

The difficulty lies in the processing after the search: the processing of the remainder, the processing of large numbers, the relationship between the remainder and the desired multiples.

 

Let's talk about how to deal with the problem of large numbers and pruning:

Let's start with a brief look at the naïve 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) has a solution

(111*10+1)%6=1 (k=1111) because of the previous solution, the remainder is not stored

}

}

}

From the above, we can see the order of the remainder (storage by layer):

Store remainder with array mod[], where mod[0] is not used, starting with mod[1]

Then the remainder of the mod is: 1 4 5 4 5 2 3 4 5 2 3 2 3 0 Total 14

That is, we get the remainder 0 before, do 14 steps *10 operation, then when the n value is large enough, it is very easy to appear k for large number of cases (in fact, I have done statistics, 200 of the N, there are 18 n corresponding to the K value for the large number

Then it would be unwise for us to use int to store K.

In order to deal with all cases, we naturally think that we should use int[] to store every bit of K.

And because K is a 01 sequence, that can be *10 to get k each bit of the problem into a modulo 2 operation to get every bit of K (0 or 1) it.

The answer is yes.

First, we use the same comodule theorem to optimize the method of obtaining the remainder.

(a*b)%n = (a%n *b%n)%n

(a+b)%n = (a%n +b%n)%n

Take one of the above clauses as an example

the previous step (11*10+1)%6=2 is k=110, k%6=2

Current Step (110*10+1)%6=2

By the same comodule theorem (110*10+1)%6 = ((110*10)%6+1%6)%6 = ((110%6 * 10%6)%6 +1)%6

It is not difficult to find the underscore part 110%6 equals (11*10+0)%6 = 2

so the current step (110*10+1)%6 can be converted to (2*10+1)%6=2

 

Obviously, this treatment equates k=110 to k=2

That is to replace the K value of the current step with the remainder obtained in the previous step

and N in the range of 200, the residual value can not exceed 3 digits, which solves the problem of large numbers

 

By this method, we simply store a remainder array mod[] in the BFS, we can get mod[i by mod[i-1], until the end of the mod[i]==0, greatly reducing the computational time

As mentioned earlier, n=6, the operation of the remainder of the 14 times, corresponding to the *10, BFS operation also carried out 14 times.

So i=14, by observing that i%2 happens to be the lowest digit of a multiple of 6.

I/2 again make i%2, happens to be a multiple of 6 sub-low number ...

Loop this operation until the i=0, you can get 6 01 times times (a 01 queue), the reverse output is the request

This completes the transition of the *10 operation to%2

Because the n value is limited, only 1 to 200 of integers, so the subject can also be used to make a table, through the above method to obtain results, the 1~200 multiples of print out, re-establish a program, directly hit the table can be.

But the table is not much faster than the method described above.

Memory time
//2236k  32MS 

#include <iostream>
using namespace std;

int mod[524286];  Save the remainder of each mod n
                  //Since the remainder sequence of 198 is the longest
                  //after repeated two-minute verification, 436905 is able to store a minimum of 198-odd sequence of space
                  ///But POJ definitely crosses the test again ... 524286 is the minimum limit of AC, otherwise the re

int main (int i)
{
	int n;
	while (Cin>>n)
	{
		if (!n) break
			;

		mod[1]=1%n;  Initialization, the highest bit of n multiples must be 1 for

		(i=2;mod[i-1]!=0;i++)  //using the same comodule theorem, the remainder of the previous step MOD[I/2] get the remainder of the next mod[i]
			mod[i]= (mod[i /2]*10+i%2)%n;
		             The mod[i/2]*10+i%2 simulates the two-entry search for BFS
		             //When I is even, +0, which is the current bit number 0  . is an odd number, then +1, that is, take the current digit is 1

		i--;
		int pm=0;
		while (i)
		{
			mod[pm++]=i%2;   Convert the *10 operation to%2 operation, reverse the multiplier of each digit
			i/=2;
		}
		while (PM)
			cout<<mod[--pm];  Reverse output
		cout<<endl;
	}
	return 0;
}




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.