题目
输入样例:
6
输出样例:
2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4
思路
1、首先我们可以将n个数全排列,这样就可以使得每行和每列有且只有一个棋子。
2、然后我们考虑如何使得每条对角线只有一个棋子。我们发现如果两个棋子所在列数差值的决定值等于两个棋子所在行数差值的绝对值,那么这两个棋子就在对角线处。
3、再次优化我们算法,如何剪枝呢?我们可以再访问的这个数字时先判断如果这个数字放入改行是否位于上面所有行的对角线处,如果符合不进行标记,直接访问下一个元素。
代码
#include <iostream>
using namespace std;
int vis[13]={0}; //标记元素是否访问过//
int result[13]={0}; //结果//
int sum=0;
int N;
void dfs(int count)
{
if (count==N) //DSF出口//
{
sum++;
if (sum<=3){
for (int i = 0; i <N ; ++i) {
cout<<result[i]<<" ";
}
cout<<endl;
}
}
for (int i = 0; i <N ; i++) { //第一次//
bool flag=true;
if (vis[i]==0){
for (int j = 0; j <count ; ++j) { //剪枝判断//
if (abs(i+1-result[j])==abs(j-count)){
flag= false;
break;
}
}
if (flag== true)
{
vis[i]=1;
result[count]=i+1;
dfs(count+1);
vis[i]=0;
}
}
}
}
int main (){
cin>>N;
dfs(0);
cout<<sum<<endl;
return 0;
}