dfs最重要的使搜索顺序。即使用什么顺序搜索遍历所有方案。以例题842. 排列数字
按照图中所示的顺序对所有方案进行遍历。
算法:
#include <iostream> using namespace std; const int N = 10; int path[N]; int 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(u + 1); // 恢复现场 path[u] = 0; st[i] = false; } } } int main() { cin >> n; dfs(0); return 0; }
#include <iostream> using namespace std; const int N = 10; 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; } for (int i = 0; i < n; ++i) { 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; }
注意对角线的处理,s表示放置n皇后的数目。记住需要恢复现场
步骤:
#include <iostream> using namespace std; const int N = 20; int n; char g[N][N]; bool col[N], dg[N], udg[N], row[N]; void dfs(int x, int y, int s) { // s 表示摆放的皇后个数 if (y == n) y = 0, ++x; if (x == n) { // 如果放置皇后数量 == n if (s == n) { for (int i = 0; i < n; ++i) puts(g[i]); puts(""); } return; } // 不放皇后 dfs(x, y + 1, s); // 放皇后 if (!row[x] && !col[y] && !dg[x + y] && !udg[x - y + n]) { g[x][y] = 'Q'; row[x] = col[y] = dg[x + y] = udg[x - y + n] = true; dfs(x, y + 1, s + 1); row[x] = col[y] = dg[x + y] = udg[x - y + n] = false; g[x][y] = '.'; } } int main() { cin >> n; for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) g[i][j] = '.'; dfs(0, 0, 0); return 0; }