很明显本题要用到深度搜索dfs, 每次搜索都从第一行开始
第一次先从第一行第一列, 若搜索成功满足条件:
1、本列没有其他数 vis1[i]==0
2、该数对应的 左上到右下的对角线 没有其他数——vis2[i - cur + n]==0 我们可以发现!每条对角线上的横纵坐标之差始终相等 但是有的可能出现负数的情况 因此这里我们加上n 至于(i - cur)还是(cur - i)都是可以的 前后保持一致即可
3、该数对应的 右上到左下的对角线 没有其他数——vis3[i + cur]==0 我们也可以发现!!每条对角线横纵坐标之和相等!
则向第二层进发——dfs(cur + 1)
注意!此处不能是++cur !! cur不能改变 因为每次的最初都是要从第一行开始的! 血的教训!!
这样一直向下搜索~~
如果顺利的话就一直向下知道最后一行这时cur == n + 1(这时一层一层向下递归导致的结果)——输出!
若到某一行没有满足条件的则进行回溯,返回上一行换一个重新开始
AC代码(含详细注释):
#include<bits/stdc++.h>//万能头文件
using namespace std;
vector <int> vec;//使用vector(可以理解为动态的数组)
int n, ans = 0;//n为行列数 ans记录答案个数
int vis1[100];//列 起一个标记作用 以便于看他对应的列是否已经有其他数了
int vis2[100];//右斜 起一个标记作用 以便于看他对应的列是否已经有其他数了
int vis3[100];左斜 起一个标记作用 以便于看他对应的列是否已经有其他数了
void dfs(int cur)
{
if(cur > n)//若所有都满足条件
{
ans++;
if(ans <= 3)//输出前三个答案
{
for(int i = 0; i < n; i++)
{
cout << vec[i] << " ";//直接当成数组用的
}
cout << endl;
}
}
for(int i = 1; i <= n; i++)//从第一列到最后一列挨个试
{
if(!vis1[i] && !vis2[i - cur + n] && !vis3[i + cur])//满足条件否??
{
vis1[i] = 1;//标记 这一列我先占上了!
vis2[i - cur + n] = 1;//同理
vis3[i + cur] = 1;//同理
vec.push_back(i);//将符合条件的列存入vector中
dfs(cur + 1);//递归 下一层进发
vec.pop_back();//回溯
vis1[i] = 0;//撤销标记
vis2[i - cur + n] = 0;//撤销标记
vis3[i + cur] = 0;//撤销标记
}
}
}
int main()
{
cin >> n;
dfs(1);
cout << ans;
return 0;
}
觉得还不错请点个赞再走吧~~ 笔芯!