AcWing Blue Bridge Cup Special Training: (1) Recursion and recursion examples

AcWing Blue Bridge Cup Special Training: (1) Recursion and recursion examples

AcWing account ID: Koji Tiansuo

Note: It may be different from the total code of y

  1. Recursively implement exponential enumeration (master)
    randomly select any number of n integers from 1 to n, and the question finally requires us to output in ascending order.
    In the y general class, it is clearly pointed out that we can use the tree diagram to consider. For each digit, we can derive two cases of selection and non-selection. After considering the two cases, we will consider theirs in the same way. Select and unselect the next digit... and so on. As long as these two cases are considered separately, pay attention to recursive reduction .
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=16;
int n;
vector<int>path;//记录最终答案

void dfs(int u)//u代表了当前是1-n中的哪一个数,由于输出需要从小到大,故从1开始
{
    
    
    if(u == n+1)//如果这n位数都枚举完了,显然是枚举到第n+1个了
    {
    
    
        for(int i=0;i<path.size();i++)
        {
    
    
            cout<<path[i]<<" ";
        }
        cout<<endl;
        return ;//递归终止,开始回溯
    }
 
    path.push_back(u);
    dfs(u+1);//如果选了本位数,就push进去
    path.pop_back();//递归还原
    
    dfs(u+1);//如果没选本位数。
}
int main()
{
    
    
    cin>>n;
    dfs(1);
    return 0;
}
  1. The problem of recursively implementing exponential enumeration (mastering)
    requires us to disrupt the order of 1-n, and at the same time require the smaller lexicographic order to come first. So we use for to enumerate each digit in our 1-n and mark that we have used this digit. Here we use a recursive idea to solve:
    Take the i = 1 bit example, we take the first number After choosing i = 1 and pushing it into the path array, then we recursively to the next level by choosing a number from i=2->n.
    In the same way, we can also choose not i=1 for the first level of recursion. Through for we can choose i=2,3…n as the first number and mark it to prevent repetition, and then recurse to the next level that has never been marked. The winner is your next digit. Also pay attention to recursive restoration !
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=10;
int n;
vector<int>path;
bool st[N];

void dfs(int u)
{
    
    
    if(u == n)
    {
    
    
        for(int i=0;i<path.size();i++)
        {
    
    
            cout<<path[i]<<" ";
        }
        cout<<endl;
        return ;
    }
    for(int i=1;i<=n;i++)
    {
    
    
        if(!st[i])
        {
    
    
            path.push_back(i);
            st[i]=true;
            dfs(u+1);
            st[i]=false;
            path.pop_back();
        }
    }
}
int main()
{
    
    
    cin>>n;
    dfs(0);
    return 0;
}

  1. There is nothing to say about the Fibonacci sequence (master) problem, just ordinary recursion.
#include<bits/stdc++.h>
using namespace std;
int a[100010];
int main()
{
    
    
    int n;
    cin>>n;
    if(n==1)
    {
    
    
        cout<<"0"<<endl;
    }
    else
    {
    
    
    a[0]=0;
    a[1]=1;
    cout<<"0"<<" "<<"1"<<" ";
    for(int i=2;i<=n-1;i++)
    {
    
    
        a[i]=a[i-1]+a[i-2];
        cout<<a[i]<<" ";
    }
    cout<<endl;
    }
    return 0;
}
  1. Inexplicable switch (try to understand)
    the core idea of ​​this question is:
    first of all, each grid actually only needs to be clicked. If you press an even number, it will have no effect. If you press an odd number, it is equivalent to an even number +1, which is the same as pressing. Does not comply with the principle of minimum steps.
    At the same time, the on/off of the bulb is equivalent to 0/1 in binary, we can control the turn off and turn on of the light through bit operation.
//首先每个格子都只能按一下,如果按偶数下那么没有效果,如果按技术下,又和1下相同,不符合最小步数原理
#include<bits/stdc++.h>
using namespace std;
const int N=6;
char g[N][N],backup[N][N];
int dx[5]={
    
    -1,0,1,0,0};
int dy[5]={
    
    0,1,0,-1,0};
void turn(int x,int y)
{
    
    
    for(int i=0;i<5;i++)
    {
    
    
        int a=x+dx[i];
        int b=y+dy[i];//二进制48 49 分别为110000,110001,只差1,所以可以亦或
    if(a<0||a>=5||b<0||b>=5)
    {
    
    continue;}
    g[a][b]^=1;
    }//由于字符型0的asicii值为48,1的为49,亦或即便为对位上的相反的数,所以只有最后一位对位相反
}
int main()
{
    
    
    int T;
    cin>>T;
    while(T--)
    {
    
    
        for(int i=0;i<5;i++)
        {
    
    
            cin>>g[i];
        }
        int res=10;//最大步数
        for(int op=0;op<32;op++)//第一行可以变成32种可能性,依据按与不按分为32种情况,设1为可以0为不可以
        {
    
    //例如10001为操作第一位和最后一位
            memcpy(backup,g,sizeof g);
            int step=0;
            for(int i=0;i<5;i++)
            {
    
    
                if(op>>i&1)//二进制位运算,代表着如果op的二进制数中为0则不操作,为1则可操作(选或不选问题)
                {
    
    //所以对5位二进制数的每一位枚举只要有一就改变
                    step++;
                    turn(0,i);//改变原有的亮光程度
                }
            }
            for(int i=0;i<4;i++)//一次枚举剩下的4x5
            {
    
    
                for(int j=0;j<5;j++)
                {
    
    
                    if(g[i][j]=='0')
                    {
    
    
                        step++;
                        turn(i+1,j);//下面决定上面,当上面有0的时候,摁下面
                    }
                }
            }
            bool dark=false;
            for(int i=0;i<5;i++)
            {
    
    
                if(g[4][i]=='0')
                {
    
    
                    dark=true;
                    break;
                }
            }
            if(!dark)
            {
    
    
                res=min(res,step);
            }
            memcpy(g,backup,sizeof g);//还原
        }
        if(res>6)
        {
    
    
            cout<<"-1"<<endl;
        }
        else
        {
    
    
            cout<<res<<endl;
        }
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_44067773/article/details/112856908