Recursion and recursion

Keywords: C++ Algorithm

Recursion and recursion (2)

1.Simple Fibonacci

The following sequence 0 1 1 2 3 5 8 13 21... Is called Fibonacci sequence.

This sequence starts with Item 3, and each item is equal to the sum of the first two items.

Enter an integer N, please output the first N items of this sequence.

Input format
An integer N.

Output format
Output the first N items of Fibonacci sequence in one line, separated by spaces.

Data range
0<N<46
Input example:
5
Output example:
0 1 1 2 3

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

const int N=50;
int f[N];
int n;

int main(){
 	cin>>n;
	f[0]=0;//Set initial values for the first and second numbers
	f[1]=1;
    for(int i=2;i<n;i++) f[i]=f[i-2]+f[i-1];//Recursive implementation
    for(int i=0;i<n;i++) cout<<f[i]<<" ";
    cout<<endl;
    return 0;
}

2.Puzzling switch

Have you ever played "pull the lights"?

25 lights in a row 5 × 5 square.

Each light has a switch, and the player can change its state.

At each step, the player can change the state of a light.

Players changing the state of a lamp will have a chain reaction: the lights adjacent to the lamp up, down, left and right should also change their state accordingly.

We use the number 1 to represent an open lamp and the number 0 to represent a closed lamp.

The following state

10111
01101
10111
10000
11011
After changing the status of the lamp in the top left corner, it will become:

01111
11101
10111
10000
11011
After changing the lamp in the middle of it, the state will become:

01111
11001
11001
10100
11011
Given the initial state of some games, write a program to judge whether the player can turn on all the lights within 6 steps.

Input format
In the first line, enter a positive integer n, which represents that there are n initial game states to be solved in the data.

The following lines of data are divided into n groups, each group of data has 5 lines, each line has 5 characters.

Each set of data describes the initial state of a game.

Each group of data is separated by a blank line.

Output format
A total of n lines of data are output, and each line has an integer less than or equal to 6, which indicates that it takes at least several steps to turn on all lights for the corresponding game state in the input data.

For an initial state of a game, if all lights cannot be turned on within 6 steps, output − 1.

Data range
0<n≤500
Input example:
3
00111
01011
10001
11010
11100

11101
11101
11110
11111
11111

01111
11111
11111
11111
11111
Output example:

3
2
-1

Problem solving ideas:

Set two arrays, one for reading and the other for backup. In each selection process, backup g to backup, and then operate g. after the operation, copy the backup to g, which is equivalent to restoring the original field. Secondly, the order can be arbitrary, and each grid can be selected at most once (the minimum number of steps is required, otherwise multiple switches are useless)

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

const int N=6;
char g[N][N],backup[N][N];
int T;
int dx[5]={-1,0,1,0,0},dy[5]={0,1,0,-1,0};


void turn (int x,int y)
{
    for(int i=0;i<5;i++)
    {
        int a=dx[i]+x,b=y+dy[i];
        if(a<0||a>=5||b<0||b>=5) continue;//Cross border skip
        g[a][b]^=1;//Tips: change the '0' of the character type to '1', or change the '1' of the character type to '0', the '0'ascii code is 48 and the '1'ascii code is 49, which are expressed in binary as 1100011001 respectively, which can be used for direct XOR operation
        //Of course, it can also be judged directly if else
    }
}

int main(){
   cin>>T;
   while(T--)//Cycle T inputs
   {
       for(int i=0;i<5;i++) cin>>g[i];//Line by line input
       
        int res=10;//An appropriate number can be compared with the following step
       for(int op=0;op<32;op++)//There are 5 locations. Each location has two cases of 0 and 1, a total of 2 ^ 5
       {
           int  step=0;
           memcpy(backup,g,sizeof g);
           for(int i=0;i<5;i++)//First judge the lights in the first row
           {
               if(op>>i&1)//The i th lamp
               {
                   step++;//count
                   turn(0,i);//Change the state of the lights around the first row and column i
               }
           }
           
           for(int i=0;i<4;i++)
           {
               for(int j=0;j<5;j++)
               if(g[i][j]=='0')
               {
                   step++;
                   turn(i+1,j);
                   
               }
           }
                    //The operation of the i+1 line switch is completely determined by the on-off state of the i line lamp. When i+1=n, judge whether the last line is all on
            
            bool dark=false;
            for(int i=0;i<5;i++)//Traverse the lights in the last row. At this time, if there are lights with 0 in the last row, it can no longer be turned off, so - 1 is output
            {
                if(g[4][i]=='0')
                {
                    dark=true;
                    break;
                }
            }
            if(!dark) res=min(res,step);
            memcpy(g,backup,sizeof g);
       }
       if(res>6) res=-1;
       cout<<res<<endl;
   }
   return 0;
}

3.Band fraction

100 can be expressed as a fraction: 100 = 3 + 69258714
It can also be expressed as: 100 = 82 + 3546197
Note: in the band fraction, the numbers 1 ∼ 9 appear respectively and only once (excluding 0).

Like this band fraction, 100 has 11 representations.

Input format
A positive integer.

Output format
The output and input numbers form all kinds of numbers represented by fractions without repetition and omission with the number 1 ∼ 9.

Data range
1≤N<106
Input example 1:
100
Output example 1:
11
Input example 2:
105
Output example 2:
6

Problem solving ideas:

This problem adopts a relatively simple solution: use the partition method to divide the 9 numbers into three parts. In the dfs function, the parameter u passed in indicates how many numbers are currently selected. Set u==9 as the recursive return condition, if u= 9 enters recursion and assigns a value to num

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

const int N=11;
bool used[N];
int num[N];//Store a number of segments
int n;
int ans;

int calculate(int a,int b)//From number a to number b
{
    int x=0;//Local variables to initialize
    for(int i=a;i<=b;i++)
    {
        x=x*10+num[i];
    }
    return x;
}

void dfs(int u)
{
    if(u==9)
    {
        for(int i=0;i<7;i++)
            for(int j=i+1;j<8;j++)
               {
                int a=calculate(0,i);//Partition method first number
                int b=calculate(i+1,j);//Partition method to divide the second number
                int c=calculate(j+1,8);//Calculate the remaining number as the third number
                if(a*c+b==n*c)
                    ans++;
               }
        
    }
    
    for(int i=1;i<=9;i++)
    {
        if(!used[i])
        {
            used[i]=true;
            num[u]=i;//Assign value to num[u]
            dfs(u+1);
            used[i]=false;
        }
    }
}

int main(){
    cin>>n;
    dfs(0);//How many numbers are currently selected
    cout<<ans<<endl;
    return 0;
    
}

(recursive) 4 Flip a coin

Xiao Ming is playing a coin flipping game.

There are some coins in a row on the table. We use * for the front and o for the back (lowercase letters, not zero).

For example, the possible situation is: oo*oooo

If you flip the two coins on the left at the same time, it becomes: oooo***oooo

Now Xiao Ming's question is: if you know the initial state and the target state to be achieved, you can only flip two adjacent coins at the same time, how many times should you flip at least for a specific situation?

We agreed that flipping two adjacent coins is called one-step operation.

Input format
Two lines of equal length strings represent the initial state and the target state to be achieved respectively.

Output format
An integer representing the minimum number of operation steps

Data range
The length of the input string shall not exceed 100.
The data ensure that the answer must be solved.

Input example 1:

**********
o****o****

Output example 1:
5
Input example 2:

*o**o***o***
*o***o**o***

Output example 2:
1

Problem solving ideas:

For the recursion problem, you only need to recurs n-1 times. Each time, you only need to check whether the characters corresponding to a and b are the same. If they are different, turn over a[i],a[i+1], and then judge i+1,i+2

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

string a,b;


void turn(int i)
{
    if(a[i]=='*') a[i]='o';
    else a[i]='*';
}

int main(){
    int res=0;
    cin>>a>>b;
    for(int i=0;i<a.size()-1;i++)//Just recurs n+1 times
    {
        if(a[i]!=b[i])
        {
            res++;
            turn(i),turn(i+1);//Flip the i-th number and i+1 number
        }
    }
    cout<<res<<endl;
    return 0;
}

Summary:

It can be seen that recursion can be regarded as a dfs deep search tree, each state can be regarded as each layer of the tree, and the value to be selected in each state can be regarded as each branch of the node of the tree; As long as you draw the picture step by step and deduce it step by step, it will be much simpler. Recursion and recursion will come to an end here. In the next issue, there will be an article on dichotomy and prefix sum. The code word is not easy. Please move your little finger to light up the little red heart~

Posted by Ristiisa on Sun, 07 Nov 2021 22:31:43 -0800