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

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

AcWing account ID: Koji Tiansuo

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

  1. The recursive realization of combined enumeration (mastery) is
    actually an upgraded version of the 94 question. The difference is that m is selected from n numbers and does not need to be repeated (the composition of any two groups in the answer group They are not the same, for example, 1 2 3 and 2 1 3 are repeated) .
    The first difference to solve is that u returns when enumerating to m (extract m from n), and the range of enumeration is 1-n. Like question 94, we select this number and mark it and pay attention to recursive restoration . But how do we solve that 2 1 3 is the same as 1 2 3? At this time, we add a new parameter start, which means that the numbers at the next level of recursion are all 即dfs(u+1,i+1);i+1 in the back of the previous level , which also shows that the array in the final answer we get can only be incremented.
#include <bits/stdc++.h>
using namespace std;
const int N = 25;
vector<int> path;
bool st[N];
int n,m;

void dfs(int u,int start)
{
    
    
    if(u == m)
    {
    
    
        for(int i=0;i<path.size();i++)
        {
    
    
            cout<<path[i]<<" ";
        }
        cout<<endl;
        return ;
    }
    for(int i=start;i<=n;i++)
    {
    
    
        if(!st[i])
        {
    
    
            path.push_back(i);
            st[i]=true;
            dfs(u+1,i+1);
            st[i]=false;
            path.pop_back();
        }
    }
}
int main()
{
    
    
    cin>>n>>m;
    dfs(0,1);
    return 0;
}
  1. Mixed number (mastery)
    First, we divide this mixed number into n=a+b/c.
    We can use the previous 94th question to arrange 1-9 in different ways ( questions require 1-9 to be Use ) Store the result in the st array. After that, we began to divide the st array:
    these three loops represent the three numbers a, b, and c.
    The range of the first level loop is the 0th to 7th digits of the array subscript, and we enumerate the length of the first number a (note that i is up to 7 which is a total of 8 digits, and the last digit is reserved for the second level loop) Then the range of the first number a in the array is [0,i]; in the
    second level of loop, we start from the next digit of the first level of loop, and the range of the same second number b in the array is enumerated j Get [i+1,j]; (i is the end of the previous number) the
    pruning place : we already have the first two paragraphs, the third number c does not need to loop in the range of st naturally is [j+1 ,8]; (total 8 numbers)
    Then we are opening a function to add the numbers in the array bit by bit to get a, b, c respectively. Finally, calculate whether the result is equal to our final answer through a+b/c.
#include<bits/stdc++.h>
using namespace std;
const int N=10;
int used[N];
int st[N];
int n;
int cnt=0;
bool check(int a,int b,int c)
{
    
    
    return (a+(b/c)==n)&&(b%c==0);
}
int cal(int l,int r)
{
    
    
    int res=0;
    for(int i=l;i<=r;i++)
    {
    
    
        res=res*10+st[i];//这就相当于数位每乘以一个10就会往后加一个
    }
    return res;
}
void dfs(int u)
{
    
    
    if(u>8)
    {
    
    
        for(int i=0;i<8;i++)
        {
    
    
            for(int j=i+1;j<8;j++)//这里如果i=7那么下面自动到i=8最后一个数位
            {
    
    
                int a=cal(0,i);//通过改变端点值来控制位数的不同
                int b=cal(i+1,j);//及控制前面的整数和分数不同
                int c=cal(j+1,8);
                if(check(a,b,c))
                {
    
    
                    cnt++;
                }
            }
        }
        return ;
    }
    for(int i=1;i<=9;i++)//将1-9以不同的顺序存入数组当中
    {
    
    
        if(!used[i])
        {
    
    
            used[i]=1;
            st[u]=i;
            dfs(u+1);
            used[i]=0;
            st[u]=0;
        }
    }
}
int main()
{
    
    
    cin>>n;
    dfs(0);
    cout<<cnt<<endl;
    return 0;
}



  1. If there are multiple ways to open the refrigerator in the pilot brother (understanding) question, they will open the refrigerator from top to bottom according to the priority, and from left to right in the same group.
    We only need to enumerate this 16-bit binary number to determine our solution, because the problem only needs the optimal solution, so we change the state of the handle each recursively and finally judge whether it is all on, and then compare the full amount Which one is the best solution in the solution.
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 5;
char g[N][N], backup[N][N];
int get(int x, int y)
{
    
    
    return x * 4 + y;
}
void turn_one(int x, int y)
{
    
    
    if (g[x][y] == '+') g[x][y] = '-';
    else g[x][y] = '+';
}
void turn_all(int x, int y)
{
    
    
    for (int i = 0; i < 4; i ++ )
    {
    
    
        turn_one(x, i);
        turn_one(i, y);
    }
    turn_one(x, y);
}
int main()
{
    
    
    for (int i = 0; i < 4; i ++ ) cin >> g[i];

    vector<PII> res;
    for (int op = 0; op < 1 << 16; op ++ )
    {
    
    
        vector<PII> temp;
        memcpy(backup, g, sizeof g);        // 备份

        // 进行操作
        for (int i = 0; i < 4; i ++ )
            for (int j = 0; j < 4; j ++ )
                if (op >> get(i, j) & 1)
                {
    
    
                    temp.push_back({
    
    i, j});
                    turn_all(i, j);
                }

        // 判断所有灯泡是否全亮
        bool has_closed = false;
        for (int i = 0; i < 4; i ++ )
            for (int j = 0; j < 4; j ++ )
                if (g[i][j] == '+')
                    has_closed = true;

        if (has_closed == false)
        {
    
    
            if (res.empty() || res.size() > temp.size()) res = temp;
        }

        memcpy(g, backup, sizeof g);        // 还原
    }

    cout << res.size() << endl;
    for(int i=0;i<res.size();i++)
	{
    
    
    	cout<<res[i].x+1<<" "<<res[i].y+1<<endl;
	}	

    return 0;
}


  1. Flip the coin (master) to compare s1 and s2. Here we uniformly select s2 to invert. By comparing each bit of these two strings, if there are different situations, invert s2 to the same as s1 The pattern is fine.
#include<bits/stdc++.h>
using namespace std;
char s1[1100],s2[1100];
int cnt;
int main()
{
    
    
    cin>>s1>>s2;
    int n1=strlen(s1);
    int n2=strlen(s2);
    for(int i=0;i<=n1-1;i++)
    {
    
    
        if(s1[i]!=s2[i])
        {
    
    
            if(s2[i]=='o')
            {
    
    
                s2[i]='*';
            }
            else if(s2[i]=='*')
            {
    
    
                s2[i]='o';
            }
            if(s2[i+1]=='o')
            {
    
    
                s2[i+1]='*';
            }
            else if(s2[i+1]=='*')
            {
    
    
                s2[i+1]='o';
            }
            cnt++;
        }
    }
    cout<<cnt<<endl;
    return 0;
}


Guess you like

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