DFS

大佬的解析DFS

#include<iostream>
using namespace std;
const int N = 10;
int n;
int path[N];
bool st[N];
void dfs(int u) {
	if (u == n) {
		for (int i = 0; i < n; i++) {
			cout << path[i] << ' ';
		}
		cout << endl;
		return;
	}

	for (int i = 1; i <= n; i++) {
		if (!st[i])
		{
			path[u] = i;
			st[i] = true;
/*DFS 会尽量往深处搜索,当确定当前的点不能再延伸时便会回溯。
回溯要注意恢复现场,即回溯到上一个状态。*/
			dfs(u + 1);
//注意:一直向深,不能延伸时再回溯
			st[i] = false;
		}
	}
}

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

cols(列数)和rows(行数)
***dg (对角线) 和 udg(反对角) ***

剪枝
皇后问题

#include<iostream>
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 < n; i++)puts(g[i]);
		puts("");
		return;
	}
	//y=-x+b -> b=y+x  dg=i+u
	//x是行,y是列  坐标
	for (int i = 0; i < n; i++)
        //按行枚举,不需要row
		if (!col[i] && !dg[u + i] && !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 >> n;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			g[i][j] = '.';
	dfs(0);
	return 0;
}

皇后问题原始做法

// n 皇后问题的原始做法
#include<iostream>
using namespace std;

const int N = 20;

int n;
char g[N][N];
bool row[N], col[N], gd[N], ugd[N]; // 行,列,主对角线,副对角线 

void dfs( int x, int y, int s ) // x 为行号,y 为列号,s 为已经定位的皇后个数 
{
    if( y == n )    // 已经遍历完 x 行的每列 
    {
        x++;    // 下一行 
        y = 0;  // 重新从第 0 列开始 
    }

    if( x == n ) // 遍历完 x 行
    {
        if( s == n )  // 已经全部定位完 n 个皇后 
        {
            for( int i = 0; i < n; i++ ) puts( g[i] );  // 输出结果 
            puts("");   
        }
        return;
    }

    // ( x, y ) 不放皇后,直接判断下一个格子,定位的皇后数 s 没有变化 
    dfs( x, y + 1, s ); 

    // 若在 ( x, y ) 放皇后,则要判断该位置是否符合条件 
    // 若条件满足,接着向后判断,否则剪枝(即不用再向后遍历) 
    if( !row[x] && !col[y] && !gd[ x + y ] && !ugd[ x - y + n ] )
    {
        // 符合条件 
        g[x][y] = 'Q';
        row[x] = col[y] =gd[ x + y ] = ugd[ x - y + n ] = true;

        // 继续向后遍历 
        dfs( x, y + 1, s + 1 );

        // 恢复现场 
        row[x] = col[y] = gd[ x + y ] = ugd[ x - y + n ] = false;
        g[x][y] = '.';
    }

}

int main()
{
    scanf( "%d", &n );

    for( int i = 0; i < n; i++ )
        for( int j = 0; j < n; j++ )
            g[i][j] = '.';

    dfs( 0, 0, 0 );

    return 0;
}
posted @ 2024-07-28 21:06  某朝  阅读(30)  评论(0)    收藏  举报