Search and graph theory:

Posted by Isoss on Thu, 27 Jan 2022 12:09:44 +0100

DFS, BFS algorithm and Application

DFS (depth first search)

Using stack to achieve, commonly known as violent search, the most important thing is the order and recovery of the scene
Space complexity: \ (O(h) \)
It does not have the shortest time and is suitable for strange topics with high space requirements.

842. Arrange numbers (full arrangement)

Given an integer \ (n \), there are many ways to arrange numbers \ (1 \sim n \) in a row. Now, please output all the arrangement methods in dictionary order.

Input format
A line containing an integer \ (n \).

Output format
Output all arrangement schemes in dictionary order, and each scheme occupies one line.

Data range
\(1≤n≤7\)

Input sample:

3

Output example:

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

DFS algorithm idea:
(from AcWing) DFS, that is, depth first search, the core idea is to find a way to the end, and then step back and continue in another direction.
Among them, it is necessary to mark the current node back to as accessible when recursive, that is, the recovery site will be st[i] = false.

Code:

#include <iostream>
#include <cstdio>

using namespace std;

const int N = 10;
int n, path[N]; //n is the number to enter, and path is the array used to record the path
bool st[N]; //st is used to record whether the path is accessed

void dfs(int num_dfsed)
{
	if (num_dfsed == n) //When the number to be searched reaches the end, it indicates that this path has been searched and can be printed
	{
		
	}
}

843. n-queen problem

The n-queen problem refers to placing n queens on the n * n chess board so that queens cannot attack each other, that is, any two queens cannot be in the same row, column or slash. Now, given the integer n, please output all the pieces that meet the conditions. The input format consists of one line, including integer n.

Output format each solution occupies n lines, and each line outputs a string of length n to represent the complete chessboard state. Including "." It indicates that the grid status of a certain position is empty, "Q" indicates that there is a queen on the grid of a certain position. After each scheme is output, a blank line is output. The sequence of output schemes is arbitrary, as long as there is no repetition and no omission.

Data range 1 ≤ n ≤ 9 input example: 4 output example: Q… …Q Q… …Q.

...Q. Q... ...Q .Q...

Algorithmic idea: the idea of this problem is similar to that of the template problem, but it also needs to maintain the columns and diagonal elements. Where, the subscripts u+i and − u+i in diagonal dg[u+i] and inverse diagonal udg[n − u+i] represent the intercept. (in order to make the subscript greater than 0, the reverse diagonal subscript needs to be added with n)

Code:

#include &lt;iostream&gt;
#include &lt;algorithm&gt;
using namespace std;

const int N = 20;
int n;
char g[N][N];
bool col[N], dg[N], udg[N];

void dfs(int u)
{<!-- -->
    if(u == n)
    {<!-- -->
        for(int i = 0; i &lt; n; i ++)  puts(g[i]);
        puts("");
        return;
    }
    
    for(int i = 0; i &lt; n; i ++)
    {<!-- -->
        if(!col[i] &amp;&amp; !dg[u + i] &amp;&amp; !udg[n - u + i])
        {<!-- -->
            g[u][i] = 'Q';
            col[i] = dg[u + i] = udg[n - u + i] = true;
            dfs(u + 1);
            col[i] = dg[u + i] = udg[n - u + i] = false;
            g[u][i] = '.';
        }
    }
}

int main()
{<!-- -->
    cin &gt;&gt; n;
    for(int i = 0; i &lt; n; i ++)
        for(int j = 0; j &lt; n; j ++)
            g[i][j] = '.';
            
    dfs(0);
    return 0;
}

BFS (width first search)

844. Maze walking

A two-dimensional integer array of n*m is given to represent a maze. The array contains only 0 or 1, where 0 represents the road that can be taken and 1 represents the wall that cannot be passed. Initially, a person is located in the upper left corner (1, 1), and it is known that the person can move one position in any direction of up, down, left and right at a time. How many times does the person need to move from the upper left corner to the lower right corner (n, m). The data guarantees that the numbers at (1, 1) and (n, m) are 0, and there must be at least one path.

The first line of the input format contains two integers n and m. The next N lines, each containing m integers (0 or 1), represent the complete two-dimensional array maze.

The output format outputs an integer representing the minimum number of moves from the upper left corner to the lower right corner.

Data range 1 ≤ n,m ≤ 100 input example: 5 5 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1 0 output example: 8

Code:

#include &lt;iostream&gt;
#include &lt;cstring&gt;
#include &lt;algorithm&gt;
using namespace std;

typedef pair&lt;int, int&gt; PII;
const int N = 110;
int n, m;
int g[N][N];//g array storage diagram
int d[N][N];//d array stores the distance from each point to the starting point
PII q[N * N];

int bfs()
{<!-- -->
    int hh = 0, tt = 0;
    q[0] = {<!-- -->0, 0};
    
    memset(d, -1, sizeof d);// The d array is initialized to - 1, indicating that there is no traversal
    d[0][0] = 0;//d array 0 indicates traversal
    
    int dx[4] = {<!-- -->-1, 0, 1, 0}, dy[4] = {<!-- -->0, 1, 0, -1};
    
    while(hh &lt;= tt)
    {<!-- -->
        auto t = q[hh ++];//Take out the team head element
        
        for(int i = 0; i &lt; 4; i ++)//Expand team leader elements
        {<!-- -->
            int x = t.first + dx[i], y = t.second + dy[i];
            if(x &gt;= 0 &amp;&amp; x &lt; n &amp;&amp; y &gt;= 0 &amp;&amp; y &lt; m &amp;&amp; g[x][y] == 0 &amp;&amp; d[x][y] == -1)
            {<!-- -->
                d[x][y] = d[t.first][t.second] + 1;
                q[++ tt] = {<!-- -->x, y};
            }
        }
    }
    
    return d[n - 1][m - 1];
} 

int main()
{<!-- -->
    cin &gt;&gt; n &gt;&gt; m;
    
    for(int i = 0; i &lt; n; i ++)
        for(int j = 0; j &lt; m; j ++)
            cin &gt;&gt; g[i][j];
    
    cout &lt;&lt; bfs() &lt;&lt; endl;
    
    return 0;
    
}


845. Eight digital

The input format takes up one line and will be 3 × The initial grid of 3 is drawn. For example, if the initial grid is as follows: 1 2 3 x 4 6 7 5 8, the input is: 1 2 3 x 4 6 7 5 8

Output format output occupies one line and contains an integer, indicating the minimum number of exchanges. If there is no solution, output "- 1".

Input example: 2 3 4 1 5 x 7 6 8 output example 19

Code:

#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;unordered_map&gt;
#include &lt;queue&gt;
using namespace std;

int bfs(string state)
{<!-- -->
    queue&lt;string&gt; q;
    unordered_map&lt;string, int&gt; d;
    
    q.push(state);
    d[state] = 0;
    
    int dx[4] = {<!-- -->-1, 0, 1, 0}, dy[4] = {<!-- -->0, 1, 0, -1};
    
    string end = "12345678x";
    while(q.size())
    {<!-- -->
        auto t = q.front();
        q.pop();
        
        if(t == end)  return d[t];
        
        int distance = d[t];
        int k = t.find('x');
        int x = k / 3, y = k % 3;
        
        for(int i = 0; i &lt; 4; i ++)
        {<!-- -->
            int a = x + dx[i], b = y + dy[i];
            if(a &gt;= 0 &amp;&amp; a &lt; 3 &amp;&amp; b &gt;= 0 &amp;&amp; b &lt; 3)
            {<!-- -->
                swap(t[a * 3 + b], t[k]);
                if(!d.count(t))
                {<!-- -->
                    d[t] = distance + 1;
                    q.push(t);
                }
                swap(t[a * 3 + b], t[k]);
            }
        }
    }
    return -1;
}

int main()
{<!-- -->
    char s[2];
    
    string state;
    for(int i = 0; i &lt; 9; i ++)
    {<!-- -->
        cin &gt;&gt; s;
        state += *s;
    }
    
    cout &lt;&lt; bfs(state) &lt;&lt; endl;
    return 0;
}