Recursive (c): alignment

Full array [Example 1] n-bit binary number.

       Write a program, input a natural number n (1 <= n <= 10), the output of full permutation of n-bit binary numbers. For example, input 3, the output sequence of eight 3-bit binary numbers: 000,001,010,011,100,101,110,111.

      (1) programming ideas.

       The idea of ​​recursion can be used to solve this problem.

       Setting the generated solutions full array of n-bit binary numbers is denoted as P (n), obviously, when n = 1, the position or setting, or set to 0, the problem is solved; when n> 1, may be considered the highest bit 0 or 1, or the lowermost position, then the same method for generating the remaining n-1 bit binary full array, i.e., recursive call P (n-1).

       Specifically:     

       A one-dimensional array to store n-bit binary number sequence generated by the generating process to the highest bit (bit n-1) generated by bit from the lowest bit (bit 0), 0 and 1 each may have two kinds of case, it is assumed to generate the k-th to n-1 bits of the n bit binary numbers an operation referred to as p (int * a, int k, int n), then this operation is:

        if (k == n) // bits 0 to n-1 th bit of all n-bit co-produced

       {

              Output;

              return; // recursive termination

       }

       a [k] = 0; // current k-th position of 0

       p (a, k + 1, n); // generate k + 1-th to n-1 bit

       a [k] = 1; // k-th position of a current

       p (a, k + 1, n); // generate k + 1-th to n-1 bit

      (2) source.

#include <iostream>

using namespace std;

void p(int *a,int k,int n)

{

       if (k==n)

       {

         for (int i=0;i<n;i++)

            cout<<a[i];

          cout<<endl;

          return;

       }

       a[k]=0;

       p(a,k+1,n);

       a[k]=1;

       p(a,k+1,n);

}

int main ()

{   

   int n,a[10];

   cin>>n;

   p(a,0,n); 

   return 0;

}

      The above example had a sequence of n-bit binary number, if each bit corresponding to one element, the elements are not representative of 0, 1 represents the element occurs; or each corresponding to a problem, the problem is not resolved on behalf of 0, 1 is representative of the problem the right solution, so we can on this basis, to solve practical problems.

[Example 2] Low-carbon life Grand Prix (2012 3rd Blue Bridge province Cup race questions).

       A television station held a low-carbon life Grand Prix. Scoring rules rather strange topic:

      Each player needs to answer 10 questions (numbered from 1-10), the more difficult the more behind. The answer, the current score doubled; failed to answer the same question number minus fraction (players must answer questions not answered by error handling).

      Each contestant had a starting score of 10 points.

      The final score of a winning player is just 100 points, if not let you watch the race, you can infer that he (she) which is the subject answered correctly, which it got it wrong topic?

      If the answer is denoted by 1, is referred to as a 0 wrong answer, the answer may be the case 10 containing only topic string of 0 and 1 are represented. For example: 0010110011 is possible.

      Write a program that outputs a string that represents all possible answers situation.

      (1) programming ideas.

      Example 1 produce a full idea of ​​the arrangement using a 10-bit binary numbers, each binary number respectively corresponding to the case of a question to answer, 0 for wrong answers, correct answer represents. If the calculated score exactly 100, the set of solutions is a problem.

      (2) source.

#include <iostream>

using namespace std;

void f(int s[] , int n , int score)

        int i;

       if(n>=11)

       {

            if(score == 100)

             {

                 for(i=1;i<=10;i++)  

                    cout<<s[i];

                  cout<<endl;

            }

           return;

    }

    s [n] = 0; // n-wrong answer questions

    f(s, n+1, score-n); 

    s [n] = 1; // n-correct answers

    f(s, n+1, score*2);

}

int main ()

{  int s[11]; 

   s[10] = '\0' ; 

   f(s,1,10);

   return 0;

}

[Example 3] Li Bai porter (2014 5th Blue Bridge province Cup race questions).

      Poet Li Bai, and his good drink. One day, he carried the jug, out of the house, in jug wine bucket 2. He Life on a String:

            No matter walking in the street, put the pot to play wine.

           Every shop doubled, the case took a drink bucket.

      Along the way, he met a total of five stores, flower encountered 10 times, the last known encounter was spent, he just drank up the wine.

      Please work shop and met Li Bai order flowers, you can store recorded as the case of a, the event took denoted b. Then: babaabbabbabbbb is a reasonable order. Please answer all output like this.

      (1) programming ideas.

      The same procedure of Example 1 is arranged to generate a binary number of 15, arranged for determining for each, see meets the requirements (5 stores encountered, just drinking wine, flowers last encountered), the output condition is satisfied to the corresponding character string.

      (2) source.

#include <iostream>

using namespace std;

void dfs(int *a,int k)

{

       if (k==15)

       {

          int alcohol,drinkery,i;

          alcohol=2;  drinkery=0;

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

                 if (a[i]==0)

                 {

                        alcohol=2*alcohol;

                        drinkery++;

                 }

                 else

                        alcohol--;

          if (alcohol==0 && drinkery==5 && a[14]==1)

          {

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

                        if (a[i]==0) cout<<"a";

                        else   cout<<"b";

                 cout<<endl;

          }

          return;

       }

       a[k]=0;

       dfs(a,k+1);

       a[k]=1;

       dfs(a,k+1);

}

int main ()

{   

   int a[15];

   dfs(a,0); 

   return 0;

}

      (3) program optimization.

      The above program with binary 0 indicates encountered shop, 1 encountered flower. In fact, it can be directly define a character array char a [16], the elements of the array a [0] ~ a [14] directly character 'a' or 'b' assigned, a [15] forming the end character '\ 0 '.

      Further, the arrangement 15 is generated by recursive binary number of 2 15 = 32768 kinds of cases, which is above the determined search program 32768 kinds of circumstances. In fact, due to meet the solution of the problem is encountered shop five times, so store up to 6 times in the case of a search process, certainly not the solution of the problem, no need to continue and could prune.

      To prune, and the number of times the bucket in case of need to record wine shop in the recursion function can be rewritten as

     void dfs (char * a, int k, int alcohol, int drinkery), which records the number of fighting alcohol in the wine jug, drinkery the number of times the event store records.

      After pruning optimized source code as follows:

#include <iostream>

using namespace std;

void dfs(char *a,int k,int alcohol,int drinkery)

{

       if (k==15)

       {

       if (alcohol==0 && drinkery==5 && a[14]=='b')

          {

                 cout<<a<<endl;

          }

          return;

       }

       if (drinkery<=5 && alcohol!=0)   // 剪枝

       {

              a[k]='a';

           dfs(a,k+1,2*alcohol,drinkery+1);

           a[k]='b';

           dfs(a,k+1,alcohol-1,drinkery);

       }

}

int main ()

{   

   char a[16];

   a[15]='\0';

   dfs(a,0,2,0); 

   return 0;

}

 

Here we continue to expand on the basis of Example 1 on recursive procedure.

       Example 1 is a program of the full array generates a binary number, and therefore only 0 and 1 each in both cases. If any code can be assigned to each of the 10 0-9 a, you can be in the recursive procedure in Example 1

       a [k] = 0; // current k-th position of 0

       p (a, k + 1, n); // generate k + 1-th to n-1 bit

       a [k] = 1; // k-th position of a current

       p (a, k + 1, n); // generate k + 1-th to n-1 bit

Rewritten as:

for (int i=0;i<=9;i++)
{
     a[k]=i;

     p(a,k+1,n);
}

Thus, the recursive call if the main function p (a, 0,3);, 000 to 999 may output the total of 1,000 three-digit.

       Further consideration arrangement if you need to generate a digital all different, how to do it?

       Obviously, the implementation of "a [k] = i; " before the number i (0 ~ 9 one) assigned to a [k] need to determine whether i has been used, if the number i has been used, the assignment is not performed.

      May define an array int visit [10] = {0} numerals appears, such as visit [3] = 1 represents the number 3 has already been used, visit [3] = 0 represents the number 3 has not been used. Modify the above recursive function as follows:

void p(int *a,int k,int n,int visit[])

{

     if (k==n)

    {

         for (int i=0;i<n;i++)

              cout<<a[i];

         cout<<" ";

         return;

     }

     for (int i=0;i<=9;i++)
     {
           if (!visit[i])
          {
                a[k] = i; visit[i] = 1;
                p(a,k+1,n,visit);
                visit[i] = 0;
           }
     }
}

      Array defined in the master function int x [10] and int visit [10] = {0}, recursive function is p (x, 0,3, visit), it can be output without repeating three-digit numbers 012 ~ 987 (co arrangement 720 number) of.

       If then a recursive function for a [k] assignment loop for (int i = 0; i <= 9; i ++), is rewritten as for (int i = 1; i <= n; i ++), the recursive call

Function p (x, 0,3, visit), the whole arrangement can be output by the non-repeating numbers 1,2,3 three three-digit numbers (123,132,213,231,312 and 321).

 

Sloppy formula [Example 4] (2013 4th Blue Bridge province Cup race questions)

      Xiao Ming is impatient, often in grade school teacher wrote on the blackboard topics copied wrong. On one occasion, the teacher is entitled: 36 x 495 = copy he gave became:?? 396 x 45 = but the result is very dramatic, his answer turned out to be right! Because 36 = 396 * 495 * 45 = 17820

      Such coincidences may be similar, there are many cases, such as: 594 * 27 * 54 = 297.

      Suppose a, b, c, d, e represents 1 to 9, five different numbers (note number is not the same, and no 0), to meet the form: ab * cde = adb * ce such total formula how many do?

      (1) programming ideas.

      int num [6], wherein the num [1] ~ num [5] respectively represent five elements a, b, c, d, e, define an array value. Discussion The method may be extended in front modeled, generated by the non-repeating numbers 1 to 9 nine digits of the full array 5 bits.

       1 to 9 to generate five different digital storage array after detecting a corresponding expression ab * cde == adb * ce is established or if established, is a set of solutions, and the output count.

#include <iostream>

using namespace std;

void dfs(int num[], int pos,bool visit[],int &cnt) 

 { 

      if (pos == 6) // number has 5 

      { 

         From int num [1] * 10 + num [2]; 

         cd int num [3] * 100 + num [4] * 10 + num [5]; 

         ADB int num [1] * 100 + num [4] * 10 + num [2]; 

         ce int num [3] * 10 + num [5]; 

         if(ab*cde == adb*ce) 

          { 

             cout<<ab<<"*"<<cde<<"="<<adb<<"*"<<ce<<"="<<ab*cde<<endl; 

             cnt++;

         }

         return; 

     } 

     for(int i = 1;i <= 9;i++) 

     { 

         if(!visit[i]) 

         { 

           num[pos] = i;  visit[i] = true; 

           DFS (num pos + 1, visit, cnt); 

           visit[i] = false; 

        } 

     } 

int main ()

{

       int num [6], cnt = 0;

       bool visit[10];

       for (int i=1;i<=9;i++)

              visit[i]=false;

       DFS (num, 1, visit, cnt);

       cout<<"Count="<<cnt<<endl;

      return 0;

}

[Example 5] hex number filled (2014 5th Blue Bridge province Cup race questions).

      Hexagonal shown in Figure 1, fill a total of 12 to 12 different numbers, so that the sum of the numbers 4 on each straight line and are the same. As shown in FIG. 2 as a viable filling method. In Figure 3, for you have filled out the three numbers, you calculate the figures represent the position of the asterisk is how much?

                         1 2 3

 

   (1) programming ideas.

      Define an array int a [13], wherein a [1] ~ a [12] This element 12 respectively from top to bottom, from left to right of the circle 12. The method can be extended in front modeled discussed, without generating a full array by repeating numbers 1 to 12 of the 12 digits.

       1 to 12 to generate 12 different digital storage array after the detection of the four numbers on the 6 straight lines and are all set equal, if the full equal, it is a set of solutions, and the output count.

    (2) source.

#include <iostream> 

#include <iomanip> 

using namespace std; 

int a[13]; 

int force [13];

int cnt=0; 

void dfs(int x)

       if(x == 12)

       { 

        int t[6]; 

        t[0] = a[1] + a[3] + a[6] + a[8]; 

        t[1] = a[1] + a[4] + a[7] + a[11]; 

        t[2] = a[2] + a[3] + a[4] + a[5]; 

        t[3] = a[2] + a[6] + a[9] + a[12]; 

        t[4] = a[8] + a[9] + a[10] + a[11]; 

        t[5] = a[12] + a[10] + a[7] + a[5]; 

        for(int i = 1; i < 6; ++i)

              { 

            if(t[i] != t[i-1])  return ; 

        }

        cnt++;

        cout<<"No "<<cnt<<endl;

       cout<<setw(12)<<a[1]<<endl;

        cout<<setw(3)<<a[2]<<setw(6)<<a[3]<<setw(6)<<a[4]<<setw(6)<<a[5]<<endl;

        cout<<setw(6)<<a[6]<<setw(12)<<a[7]<<endl; 

        cout<<setw(3)<<a[8]<<setw(6)<<a[9]<<setw(6)<<a[10]<<setw(6)<<a[11]<<endl;

        cout<<setw(12)<<a[12]<<endl<<endl;

        return ; 

    }  

    for(int i = 1;i < 13; ++i)

       { 

        if(!vis[i])

              { 

            view [i] = 1; 

            a[x] = i; 

            dfs(x+1); 

            view [i] = 0; 

        } 

    } 

int main ()

    for (int i=1;i<=12;i++)

          view [i] = 0; 

    vis[1] = 1; 

    a[1] = 1; 

    vis[8] = 1; 

    a[2] = 8; 

    vis[3] = 1; 

    a[12] =3; 

    dfs(3); 

    cout<<"Count="<<cnt<<endl;

    return 0; 

}  

[Example 6] difference triangle.

      Observation of the triangle following numbers:

                3

              1 4

             5 6 2

      What are the characteristics you see?

      1) It contains an integer of 1 to 6 continuously.

      2) Each number is below two adjacent difference numbers (of course, large numbers subtracting decimal)

      Such characteristics satisfy the triangle, triangle difference is called.

      Write a program to find a bigger difference between the triangle by 1 to 15 of 15 integers.

      (1) programming ideas.

      First determine the value of the last row, i.e. 5 selected full array elements 15 in that any number of 1 to 15 (6 * 5/2). Thereafter, by sequentially determining a difference value characteristic triangle above the other rows. In the process of determining the value, if a value has been used, it can not be the solution to the problem. Direct pruning, for the next search.

      (2) source.

#include <iostream>

#include <iomanip> 

#include <cmath> 

using namespace std; 

void judge(int take[],int n)

{

    bool visited [22]; // up to six rows, the number of 21  

    int num [6] [6], i, j, x;

    for (i=1;i<=n*(n+1)/2;i++)

              visited[i]=false; 

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

    { 

              num[n-1][i]=take[i];   

              visited[take[i]] = true; 

    } 

    for (i=n-2; i>=0; i--) 

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

       { 

           x = abs (num [i + 1] [j] - whether [i + 1] [j + 1]); 

           if(visited[x]) 

               return; 

           if(x>=1 && x<= n*(n+1)/2) 

           { 

               visited[x] = true; 

               whether [i] [j] = x; 

           } 

       }

       if  (num[n-1][0]>num[n-1][n-1]) return ;

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

      { 

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

               cout << setw(4)<<num[i][j]; 

           cout << endl; 

       }

       cout<<endl;

}

void dfs(int take[], int index, bool vis[],int n) 

    int i, j; 

    if (index==n) 

    { 

        judge(take,n);

        return; 

    } 

    for(i = 1; i <= n*(n+1)/2; i++) 

    { 

        if(!vis[i]) 

        { 

            vis[i] = true; 

            take[index]= i; 

            dfs(take, index+1,vis,n); 

            view [i] = false; 

        } 

    } 

int main () 

    int n,take[6],i;

       bool Show [22];

    cin>>n;

    for(i = 1; i <= n*(n+1)/2; i++) 

       view [i] = false; 

    dfs(take,0,vis,n);

    return 0; 

}  

[Example 7] mixed number (2013 4th Blue Bridge province Cup race questions) .

      100 may be represented in the form of mixed fractions: 69 258 + 3 = 100/714

      It can also be expressed as: 82 + 100 = 3546/197

      Mixed fraction like this, there are 11 100 notation.

      It is emphasized that: a mixed fraction, the numbers 1 to 9 appears once and only once, respectively (not including 0).

      Write a program, input a positive integer N (N <1000 * 1000), with the output of the digital number N 1 ~ 9 will not be repeated without omission mixed fraction consisting of all the number of species represented.

      (1) programming ideas.

      If mixed number symbolized num = m1 + m2 / m3; then the first m1 must be less than num, and because num is an integer, so m1 and m2 / m3 are integers, which requires m2 / m3 must be divisible, Therefore m2% m3 = 0, m2 / m3 can also meet other conditions, i.e., m2> = m3. Accordingly, to determine four conditions: 1) m1 <num; 2) m2% m3 = 0; 3) m2> = m3; 4) num = m1 + m2 / m3.

      Thus, by selecting the program to meet the full array is one of these four conditions required result in a full array 1 to 9.

       The method of generating a full array 1 to 9 can be referred to the previous example. The key to the present embodiment lies in how to determine the range m1, m2, m3 of the whole arrangement of 1 to 9 (nine digits) in.

      m1 values ​​should be less than num, and must be greater than or equal to m2 m3, m2 certain range after the selection m1 to select the remaining half or more of data. For example, 1 to 9, wherein a full array of 156 987 423, 156 when the select m1, m2 is selected only half or more of the remaining 987,423, as 987,9874,98742. If m2 is less than the rest of the half, then it is not satisfied division (eg 98/7432). M3 is the range of m1 and m2 selecting all the rest.

      Suppose i m1 before selecting the position 9, then the range of options for the first m2 i + (9-i) / 2 to 9-1 digits (the end of half or more, when up to 9-1, to leave m3 a number).

    (2) source.

#include <iostream>  

using namespace std;

int aws=0; 

int a[10],flag[10]; 

int sum(int start,int end) 

     int i, num = 0;   

     for(i=start;i<=end;i++)  

       num = num * 10 + a [i];   

     Surely return;  

void Found (int a [], int num) // full permutation of each of the results of DFS function is checked in Found  

     int i,j,m1,m2,m3; 

     for(i=1;i<10;i++) 

     { 

        m1 = sum (1, i); // first number selected from 1 to 9 Start   

        if (m1> = num) return; // not satisfy the first number <num directly out of the   

        for(j=i+(9-i)/2;j<9;j++) 

        { 

           m2 = sum (i + 1, j); // second number   

           m3 = sum (j + 1,9); // third number   

           if (m2>m3 && m2%m3==0 && num==m1+m2/m3) 

           { 

              cout<<num<<"="<<m1<<"+"<<m2<<"/"<<m3<<endl;  

              aws++; 

           } 

        } 

     } 

void DFS (int start, int num) // 1 ~ 9 full array   

     int i; 

     if (start==10) 

         Found(a,num); 

     else 

     { 

         for(i=1;i<10;i++) 

         { 

            if(flag[i])  

                continue;   

            a[start]=i;   

            flag[i]=1;   

            DFS (start + 1, num); // choose a good one to start next election   

            flag[i]=0; 

         } 

     } 

int main () 

    int num i; 

    for(i=1;i<10;i++)

              flag[i]=0; 

    cin>>num; 

    DFS(1,num); 

    cout<<aws<<endl; 

    return 0; 

}  

 

Guess you like

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