题目一(数字全排列)
图解dfs
代码实现
#include<iostream>
using namespace std;
const int N = 10;
int path[N], str[N], len;//path记录当前的路径, str判断是否重复, len记录数字范围
void dfs(int n)
{
if(n == len + 1)
{
for(int i = 1;i <= len;i ++ )
{
printf("%d ", path[i]);
}
printf("\n");
return ;
}
for(int i = 1;i <= len;i ++ )
{
if(str[i] == 0)//代表i未使用
{
str[i] ++ ;//标记i已经使用
path[n] = i;//将i放在path中的n下标的位置
dfs(n + 1);
str[i] -- ;//恢复成未使用状态
}
}
}
int main()
{
cin >> len;
dfs(1);
return 0;
}
文章图片均来自acwing
题目二(n皇后问题)
代码实现
#include<iostream>
using namespace std;
const int N = 20;
bool col[N], dg[N], adg[N];//col是判断该列是否有皇后, dg是判断该正对角线是否有皇后, adg是判断该反对角线是否有皇后
//bool数组全局变量默认为false
int str[N][N], len;//str储存皇后的排放, len为皇后数;
void dfs(int h)//h代表行数, l代表列数
{
if(h == len + 1)
{
for(int h = 1;h <= len;h ++ )
{
for(int l = 1;l <= len;l ++ )
{
printf("%c", str[h][l]);
}
printf("\n");
}
printf("\n");
return ;
}
for(int l = 1;l <= len;l ++ )
{
//反对角线adg就像y = -x + b, 其截距b = y + x(即h + l)
//正对角线dg就像y = x + b, 其截距b = y - x, 为了防止b为负数, 所以再加上固定偏移量len, 即b = y - x + len(即h - l + len);
if(!col[l] && !dg[h - l + len] && !adg[h + l])
{
col[l] = dg[h - l + len] = adg[h + l] = true;
str[h][l] = 'Q';
dfs(h + 1);
//将str, col, dg, adg复原
str[h][l] = '.';
col[l] = dg[h - l + len] = adg[h + l] = false;
}
}
}
int main()
{
cin >> len;
for(int i = 1;i <= len;i ++ )
{
for(int j = 1;j <= len;j ++ )
{
str[i][j] = '.';//初始化全部为.
}
}
dfs(1);//从第一行开始dfs
return 0;
}
题三
代码实现
#include<iostream>
using namespace std;
const int N = 10;
bool flag[N];
char path[N];
string emp;
int len;
void dfs(int i)
{
if(i > len)
{
for(int j = 1;j <= len;j ++ )
{
printf("%c", path[j]);
}
printf("\n");
return ;
}
for(int l = 0;l < len;l ++ )
{
char letter = emp[l];
if(!flag[l])
{
flag[l] = true;
path[i] = letter;
dfs(i + 1);
flag[l] = false;
}
}
}
int main()
{
cin >> emp;
len = emp.size();
dfs(1);
return 0;
}