#include <bits/stdc++.h>
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];
}
//不写return会继续往下走
return;
}
//生成排列的主循环
//遍历每个可能的数
for(int i=1; i<=n; i++){
//如果当前数字i没有被使用过
if(!st[i]){
//选择这个数放在当前位置u
path[u]=i;
//标记这个数已使用
st[i]=true;
//递归处理下一个位置
dfs(u+1);
//取消标记(回溯)
st[i]=false;
}
}
}
int main(){
cin>>n;
dfs(0);
return 0;
}
语句的执行顺序分析
两点说明:
①u 的回退是由递归栈的结构自动处理的,不需要显式地进行 u-- 操作。
②等递归函数执行完后(也就是 return 了),程序才会执行st[i]=false;
#include <bits/stdc++.h>
const int N=20;
// 棋盘大小(即皇后个数)
int n;
//棋盘,每个位置是 '.' 或 'Q'
char g[N][N];
//列、对角线、反对角线
bool col[N],dg[N*2],udg[N*2];
using namespace std;
void dfs(int u){
//如果所有行都放置完毕,说明找到一个合法的方案
if(u==n){
for(int i=0; i<n; i++){
for (int j = 0; j < n; j++) {
cout << g[i][j];
}
cout<<endl;
}
cout<<endl;
return;
}
//尝试在第u行的每一列放皇后
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]='.';
}
// 每行末尾手动加 '\0',确保是合法字符串
g[i][n] = '\0';
}
dfs(0);
return 0;
}