Exhaustive (IV): two-exhaustive examples on POJ POJ 1411 and POJ 1753

      Here are two questions on the POJ, to see how to solve with brute-force method.

【例9】Calling Extraterrestrial Intelligence Again(POJ 1411)

Description

A message from humans to extraterrestrial intelligence was sent through the Arecibo radio telescope in Puerto Rico on the afternoon of Saturday November 16, 1974. The message consisted of 1679 bits and was meant to be translated to a rectangular picture with 23 x 73 pixels. Since both 23 and 73 are prime numbers, 23 x 73 is the unique possible size of the translated rectangular picture each edge of which is longer than 1 pixel. Of course, there was no guarantee that the receivers would try to translate the message to a rectangular picture. Even if they would, they might put the pixels into the rectangle incorrectly. The senders of the Arecibo message were optimistic.

We are planning a similar project. Your task in the project is to find the most suitable width and height of the translated rectangular picture. The term "most suitable" is defined as follows. An integer m greater than 4 is given. A positive fraction a/b less than or equal to 1 is also given. The area of the picture should not be greater than m. Both of the width and the height of the translated picture should be prime numbers. The ratio of the width to the height should not be less than a/b nor greater than 1. You should maximize the area of the picture under these constraints.

In other words, you will receive an integer m and a fraction a/b. It holds that m > 4 and 0 < a/b <= 1. You should find the pair of prime numbers p, q such that pq <= m and a/b <= p/q <= 1, and furthermore, the product pq takes the maximum value among such pairs of two prime numbers. You should report p and q as the "most suitable" width and height of the translated picture.

Input

The input is a sequence of at most 2000 triplets of positive integers, delimited by a space character in between. Each line contains a single triplet. The sequence is followed by a triplet of zeros, 0 0 0, which indicates the end of the input and should not be treated as data to be processed.

The integers of each input triplet are the integer m, the numerator a, and the denominator b described above, in this order. You may assume 4 < m <= 100000 and 1 <= a <= b <= 1000.

Output

The output is a sequence of pairs of positive integers. The i-th output pair corresponds to the i-th input triplet. The integers of each output pair are the width p and the height q described above, in this order.

Each output line contains a single pair. A space character is put between the integers as a delimiter. No other characters should appear in the output.

Sample Input

5 1 2

99999 999 999

1680 5 16

1970 1 1

2002 4 11

0 0 0

Sample Output

2 2

313 313

23 73

43 43

37 53

      (1) programming ideas.

      For m inputs, for (p, q), satisfies the condition through an exhaustive search to find a set of prime numbers: 1) p, q are prime numbers, and p <= q <= m; 2) p * q <= m; 3 ) a / b <= p / q; 4) p * q has its maximum value.

      First determine exhaustive of the scope of p and q, since m is not more than 100,000, so p and q does not exceed 50,000 (as the smallest prime number is 2, 2 * 50000 = 100000). Further consideration, since 1 <= a <= b <= 1000, so the minimum value of a / b is 1/1000 = 0.001, and therefore, p / q> = 0.001. When m reaches the maximum 100,000, 100,000 / 11 = 9090.9, 2,3,5,7 prime number less than 9091 divided by 0.001, thus, can be further narrowed down p, q of a prime number to take between 2 to 9091.

      First of all the quality is less than the number of seeking out 9092, and stored in an array of prime, note prime number num.

      Exhaustive of all heavy cycle with diethyl p (prime [0] ~ prime [num-1]), q (p ~ prime [num-1]) in combination, for each combination to judge whether the conditions, if met, p * q compared with the current maximum value max, the maximum saving of p * q.

      (2) source.

#include <iostream>

using namespace std;

int main ()

{

    int flag[9092]={0},prime[5000]={0};

    int num=0,m,a,b,p,q,max,i,j;

    double s;

    for (i=2;i<9092;i++)

    {  

        if (flag[i]==0)

              {

                     prime[num++]=i;

                     for (j=2*i;j<9092;j+=i)

                            flag[j]=1;

              }

    }

    cin>>m>>a>>b;

    while(m>0)

    {  

              max=0;

        s=1.0*a/b;

        for(i=0; i<=num-1; i++)

        {  

            if(prime[i]>m) break;

            for(j=i;j<=num-1;j++)

            {

                        if(prime[j]>m||prime[j]*prime[i]>m||1.0*prime[i]/prime[j]<s)

                               break;

                         if(prime[j]*prime[i]>max)

                        { 

                                  max=prime[i]*prime[j];

                                  p=prime[i];

                                  q=prime[j];

                        }

                   }

           }

        cout<<p<<" "<<q<<endl;

        cin>>m>>a>>b;

       }

    return 0;

}

 

【例10】Flip Game(POJ 1753)

Description

Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 squares. One side of each piece is white and the other one is black and each piece is lying either it's black or white side up. Each round you flip 3 to 5 pieces, thus changing the color of their upper side from black to white and vice versa. The pieces to be flipped are chosen every round according to the following rules:

1. Choose any one of the 16 pieces.

2. Flip the chosen piece and also all adjacent pieces to the left, to the right, to the top, and to the bottom of the chosen piece (if there are any).

Consider the following position as an example:

bwbw

wwww

bbwb

bwwb

Here "b" denotes pieces lying their black side up and "w" denotes pieces lying their white side up. If we choose to flip the 1st piece from the 3rd row (this choice is shown at the picture), then the field will become:

bwbw

bwww

wwwb

wwwb

The goal of the game is to flip either all pieces white side up or all pieces black side up. You are to write a program that will search for the minimum number of rounds needed to achieve this goal.

Input

The input consists of 4 lines with 4 characters "w" or "b" each that denote game field position.

Output

Write to the output file a single integer number - the minimum number of rounds needed to achieve the goal of the game from the given position. If the goal is initially achieved, then write 0. If it's impossible to achieve the goal, then write the word "Impossible" (without quotes).

Sample Input

bwwb

bbwb

bwwb

bwww

Sample Output

4

     (1) 1 programming ideas.

      Because a grid turn any even number of times and turned 0 effect is the same, odd turn and turn once the effect is the same. Therefore, a grid or turning once, or not turning. In addition the order to turn the grid on the final result will not be affected, that first turn on the 1st grid the ability to turn on the 2nd grid and the ability to turn the 1st first turn on the 2nd grid lattice effect is the same.

      In this way, for each of the sixteen lattice grid turn or turn exhaustive both cases, the total number of exhaustive 2 16 = 65536 times.

Using a one-dimensional array int bits [16] to store the lattice 16 in the initial state, it is set to a lattice black, white is set to 0. In the illustrated state title may be described as bits [16] = {1,0,1,0,0,0,0,0,1,1,0,1,1,0,0,1}.

Title illustrates flip lattice bits [8], the need for operation

bits[8]=!bits[8]=0,   

bits[4]=!bits[4]=1,     (bits[i - 4] = !(bits[i - 4]);)

bits[9]=!bits[9]=0,     (bits[i + 1] = !(bits[i + 1]);)

bits[12]=!bits[12]=0,   (bits[i + 4] = !(bits[i + 4]);)

Since the lattice 8 at the left, it is not left grid, thus bits [i - 1]! = (Bits [i - 1]) inoperable.

Thus, flip grid 8, the state becomes {1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,1}.

MinCnt recording with variable minimum required number of lattice turn, the initial value is set to 17, because the grid 16 turned up.

      Circulating for (i = 0; i <65536; i ++) to turn on or turn combinations 16 grid exhaustive. For each case i, j-th bit binary number is determined corresponding to the i (least significant bit is set to 0, then 0 <= j <= 15) is 1, if 1, then the inverted grid j. The latter combinations flip completed, it is determined whether the current state is a solid, if so, recording the number of lattice reversed by (i is an integer of actually binary number corresponding to the number 1) the minimum value.

      (2) a source.

#include <iostream>

using namespace std;

// determine whether the current pattern of solid color

isSolidColor you (you bits [], you len)

{

    int i = 0;

    for (i = 0; i < len - 1; i++)

     if (bits[i] != bits[i + 1])

       return 0;

   return 1;

}

// change the color of the i-th lattice around its lattice (0 <= i <= 15)

void changeColor(int bits[], int i)

{

   bits[i] = !(bits[i]);

   int x = i/4;

   int y = i%4;

   if (y < 3)

     bits[i + 1] = !(bits[i + 1]);

   if (y > 0)

     bits[i - 1] = !(bits[i - 1]);

   if (x > 0)

     bits[i - 4] = !(bits[i - 4]);

   if (x < 3)

     bits[i + 4] = !(bits[i + 4]);

}

int main ()

{

    char c;

    int bits[16],new_bits[16];

    int cnt,minCnt = 17;

    int i,j,k;

    for (i = 0; i <16; i ++) // save the input pattern to the bits in the array

    {

        cin >> c;

        if(c == 'b')

          bits[i] = 1;

        else

          bits[i] = 0;

    }

    for (i = 0; i <65536; i ++) // 65,536 kinds of combinations to be exhaustive

    {

        for (j = 0; j <16; j ++) // To ensure that the initial configuration is not modified, the cache new_bits

           new_bits[j] = bits[j];

        cnt = 0;

              k=1;

              for (j = 0; j <16; j ++) // 16-bit binary combinations of the current exhaustive

        {

                     if (i & k) // this bit is 1 j, j need to flip the grid, and counted

            {

                cnt++;

                changeColor(new_bits, j);

                     }

                     k=k<<1;

              }

        if (isSolidColor (new_bits, 16)) // determines whether solid

          if (cnt < minCnt)  minCnt = cnt;

    }

    if (minCnt==17) cout << "Impossible" << endl;

    else  cout << minCnt << endl;

    return 0;

}

      (3) 2 programming ideas.

      In the above ideas 1, with an array of bits [16] to hold one kind of pattern. In fact, it may be an integer value between 0 to 65535 to a holding one pattern. Corresponding to the integer value 16 binary digits for bit 1 of the lattice j j represents black. Since a 16-bit binary number from low to high weights of the order of 1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768, therefore, one pattern is mapped value value may be a simple loop to achieve:

    char c;

    for(i = 0; i<16; i++)

    {

        cin >> c;

        if(c == 'b')

            value += bitVal[i];

    }

      Wherein, int bitVal [16] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};

      For example, the title given pattern illustrated the value is mapped to 39685, corresponding to the binary number 1001101100000101. I.e. 39685 = 32768 + 4096 + 2048 + 512 + 256 + 4 + 1.

      Flip a lattice and its lattice it is flipped around, it can be regarded as the corresponding bit is reversed. The bits of an integer a is reversed by using the bit XOR 1 implemented. Thus, the pattern of the current value, to flip a grid i (0 <= i <= 15), or just a specific value exclusive integer c [i] to.

      For example, according to the pattern subject value (value 39685), to flip the eighth grid, as it relates to the four lattice becomes inverse, XOR binary value shall 1001100010000 11, and 0x1310.

      39685 ^ (0x1310) value of 34 837, corresponding to the binary number 1000100000010101, to convert the pattern

bwbw

bwww

wwwb

wwwb

      With an array cTable [16] to store a particular integer or inversion of each grid to be different, the array is initialized to:

          int cTable[16] = {0x13,0x27,0x4E,0x8C,0x131,0x272,0x4E4,0x8C8,0x1310,0x2320,

0x4E40,0x8C80,0x3100,0x7200,0xE400,0xC800};

      Also circulating for (i = 0; i <65536; i ++) to turn on or turn combinations 16 grid exhaustive. For each case of exhaustive, so that each record value == 0 || value == 65535 Total number of grid, saving the minimum value of the number of lattice turn.

      (4) 2 source.

#include <iostream>

using namespace std;

int main ()

{

    int cTable[16] = {0x13,0x27,0x4E,0x8C,0x131,0x272,0x4E4,0x8C8,0x1310,0x2320,

0x4E40,0x8C80,0x3100,0x7200,0xE400,0xC800};

    int bitVal[16] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};

    int i,j,value = 0, chgVal;

    int cnt,minCnt = 17;

    char c;

    for(i = 0; i<16; i++)

    {

        cin >> c;

        if(c == 'b')

            value += bitVal[i];

    }

    for(i = 0; i<65536; i++)

    {

        cnt = 0;

        chgVal = value;

        for (j = 0;j < 16;j++)

            if (i & bitVal[j])

            {

                cnt++;

                chgVal ^= cTable[j];

            }

        if(chgVal==0 || chgVal==65535)

            if (cnt < minCnt)  minCnt = cnt;

    }

    if (minCnt==17) cout << "Impossible" << endl;

    else  cout << minCnt << endl;

    return 0;

}

      (5) change the thinking exhaustive.

      Two ideas foregoing sequence is exhaustive 0 to 65535, the number of the lattice selected in this order is discontinuous. The title is flipped to get the minimum number required for the grid. Therefore, the order number from exhaustive preferably this angle grid. I.e., when the 0 lattice is turned over, see the corresponding pattern whether a solid color; otherwise, selecting a grid inversion (16 choices), whether the pattern of the watch is inverted to a solid color; otherwise, select two lattice inversion (with 120 kinds of selection), the pattern of the inverted see whether solid; ......; 16 finally selected grid inversion. In this process, as long as the solid pattern appears, it is an exhaustive process ends, outputs the corresponding number of the selected grid. If the grid 16 are reversed, or did not become a solid color, output "Impossible".

Thus, the key issue is how to obtain this idea all combinations selected from the n squares in the grid 16.

      Recursive (6) combinations achieved.

      Select count different from the set numbers 1 ~ len the number of total len, and stored in the array take the operating function abstract void combineTest (int take [], int len, int count, const), then the process operation can be achieved using recursion:

       Selecting a number of count ~ len i (count <= i <= len) assigned to take [count-1]; (chose the minimum number of count, due to the number of selected count, selected from a large if the number i, have to stay count-1 smaller than the number i)

       Then i total number selected from 1 ~ i count-1 different number, i.e. the recursive call combineTest (take, i - 1, count - 1);

       End recursion conditions count == 1.

       Write recursive function as follows:

void combineTest(int take[], int len, int count,const int NUM)

{

    int i,j;

    for (i = len; i >= count; i--)

    {

       take[count - 1] = i;

      if (count >1)

        combineTest(take, i - 1, count - 1, NUM);

      else

      {

        for (j = NUM - 1; j >=0; j--)

        {

           cout<<take[j]<<"  ";

        }

        cout<<endl;

      }

    }

}

      Write the following program section to test recursive function combineTest.

   int n,m;

   cin>>n>>m;

   int *take = new int [m];

   combineTest(take,n, m, m);

   delete  [] take;

       Run this program, the input 3 and 5, to obtain the results shown below.

5

3

5  4  3

5  4  2

5  4  1

5  3  2

5  3  1

5  2  1

4  3  2

4  3  1

4  2  1

3  2  1

Press any key to continue

      (7) according to source new ideas rewrite ideas 3 1.

#include <iostream>

using namespace std;

// determine whether the current pattern of solid color

isSolidColor you (you bits [], you len)

{

    int i = 0;

    for (i = 0; i < len - 1; i++)

     if (bits[i] != bits[i + 1])

       return 0;

   return 1;

}

// change the color of the i-th lattice around its lattice (0 <= i <= 15)

void changeColor(int bits[], int i)

{

   bits[i] = !(bits[i]);

   int x = i/4;

   int y = i%4;

   if (y < 3)

     bits[i + 1] = !(bits[i + 1]);

   if (y > 0)

     bits[i - 1] = !(bits[i - 1]);

   if (x > 0)

     bits[i - 4] = !(bits[i - 4]);

   if (x < 3)

     bits[i + 4] = !(bits[i + 4]);

}

void combine(int take[], int len, int count, const int NUM, int &cnt, int bits[])

{

    int i;

    for (i = len; i >= count; i--)

    {

       if (cnt!=0)  break;

         take[count - 1] = i - 1;

       if (count > 1)

          combine(take, i-1, count-1, NUM, cnt, bits);

       else

       {

          int j = 0;

          int new_bits[16];

          for (j = 0; j < 16; j++)

            new_bits[j] = bits[j];

          for (j = NUM - 1; j >=0; j--)

                {

             changeColor(new_bits, take[j]);

                }

          if (isSolidColor(new_bits, 16))

             cnt = num;

       }

       }

}

int main ()

{

    char c;

    int bits[16];

    int i=0;

    for(i = 0; i<16; i++)

    {

        cin >> c;

        if(c == 'b')

          bits[i] = 1;

        else

          bits[i] = 0;

    }

    if (isSolidColor(bits, 16))

       cout<<0<<endl;

    else

    {

       int j;

       for (j = 1; j <= 16; j++)

          {

         int *take = new int [j];

         int cnt = 0;

         combine(take,16, j, j, cnt, bits);

         if (cnt==j)

               {

            cout<<cnt<<endl;

            delete  [] take;

            break;

               }

         delete  [] take;

          }

       if (j == 17)

       cout<<"Impossible"<<endl;

       }

    return 0;

}

      (8) is rewritten by new ideas ideas source 2 of 4.

#include <iostream>

using namespace std;

int cTable[16] = {0x13,0x27,0x4E,0x8C,0x131,0x272,0x4E4,0x8C8,0x1310,0x2320,

0x4E40,0x8C80,0x3100,0x7200,0xE400,0xC800};

int bitVal[16] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};

void combine(int take[], int len, int count, const int NUM, int &cnt, int value)

{

    int i,j,chgVal;

    for (i = len; i >= count; i--)

    {

       if (cnt!=0)  break;

         take[count - 1] = i - 1;

       if (count > 1)

          combine(take, i-1, count-1, NUM, cnt, value);

       else

       {

           chgVal = value;

           for (j = NUM - 1; j >=0; j--)

              chgVal ^= cTable[take[j]];

           if(chgVal==0 || chgVal==65535)

              cnt = num;

       }

       }

}

int main ()

{

    int i,j,cnt,value = 0;

    char c;

    for(i = 0; i<16; i++)

    {

        cin >> c;

        if(c == 'b')

            value += bitVal[i];

    }

    if(value==0 || value==65535)

       cout<<0<<endl;

    else

       {

              for (j = 1; j <= 16; j++)

              {

           cnt = 0;

           int *take = new int [j];

           combine(take,16, j, j, cnt, value);

           if (cnt==j)

                 {

              cout<<cnt<<endl;  

                       delete  [] take;

              break;

                 }

           delete  [] take;

              }

        if (j == 17)

           cout<<"Impossible"<<endl;

       }

    return 0;

}

      The source of the four sequentially submitted to POJ, to obtain the results shown in FIG. As can be seen from the figure, the better the efficiency of the source 4.

 

Figure 1 POJ displayed solve the "problem of 1753" four cases the source of the judgment

Guess you like

Origin www.cnblogs.com/cs-whut/p/11015718.html