[Basic Algorithm Notes] DFS (permuted numbers and n-queens problem)

When learning algorithms and data structures in acwing (a very good algorithm learning platform), sometimes it takes a long time to think about some topics. I will write down my thoughts and experiences during the learning process. I don’t know if I can keep writing. My own thoughts are inevitably inaccurate, and you are welcome to correct me here.​ 


DFS

Original question link:Arranging numbers - AcWing

                  n-queen problem - AcWing

The most important thing is to understand the two operations of backtracking and restoring the original state.

Backtracking: You can imagine a recursive tree. Every time a result that meets the meaning of the question is generated or the situation does not meet the meaning of the question, it will return to its previous node.

Restore the original state: Set a state array st[N] to indicate whether the location can store a value. 0 means it can be stored, 1 means it cannot be stored. Recovery operations must be performed after each backtracking.

arrange numbers

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

using namespace std;
const int N = 10000;
int p[N], st[N], n;
void dfs(int u)
{
    if(u == n)
    {
        for (int i = 0; i < n; i ++ ) cout<<p[i]<<' ';
        cout<<endl;
        return;
    }
    
    for(int i = 1; i <= n; i ++)
    {
        if(st[i] == 0)
        {
            p[u] = i;
            st[i] = 1;
            dfs(u+1);  //进行递归树的下一层
            st[i] = 0; //回溯到上一个节点,要恢复到原状态
        }
    }
}

int main()
{
    cin>>n;
    dfs(0);
    return 0;
}

n-queen problem:

The n-queen problem is essentially a problem of arranging numbers. It is a bit abstract and difficult to explain in words. It can be directly explained in a sketch. Then we have to solve the problem of how to represent the diagonal. We can abstract the n*n matrix into a plane coordinate system. The same diagonal must pass through the same b (y=x+b). So we can use the intercept b to represent the diagonal.

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

using namespace std;
const int N = 20;
int col[N], dg[N], udg[N], n, x;
char p[N][N];
// col列:记录该列的使用状态
   dg对角线,udg反对角线:记录该条对角线的使用状态
   0表示未被使用
// p[N][N]用来存结果

void dfs(int u)
{
    if( u == n) //此时已经搜索了n行,输出结果
    {
        for (int i = 0; i < n; i ++ ) cout<<p[i]<<endl;
        cout<<endl;
        return;
    }
        
    int x = u;  //搜索u这一行
    for(int y = 0; y < n; y ++) //搜索列
    {
        //判断该位置能否放置'Q',0表示未被使用
        if(col[y] == 0 && dg[y + x] == 0 && udg[y - x + n] == 0)
        {
            p[x][y] = 'Q';
            col[y] = dg[y+x] = udg[y-x+n] = 1;  //更新位置状态
            dfs(x + 1);  //搜索下一行
            p[x][y] = '.';  //恢复原状态
            col[y] = dg[y+x] = udg[y-x+n] = 0;          
        }
    }
        
}
int main()
{
    cin>>n;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n; j ++ )
            p[i][j] = '.';
    dfs(0);
}

 

Guess you like

Origin blog.csdn.net/Radein/article/details/134587518