题目描述
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。
输入
一个整数n( 1 < = n < = 10 )
输出
每行输出对应一种方案,按字典序输出所有方案。每种方案顺序输出皇后所在的列号,相邻两数之间用空格隔开。如果一组可行方案都没有,输出“no solute!”
样例输入 复制
4
样例输出 复制
2 4 1 3
3 1 4 2
分析:
完成n皇后问题可以先求出n数字的不同排列组合,每次排完进行判定,若出现斜着的就不输出该排列。而实现n数字的不同排列组合可以利用DFS思想,把排完n个数字作为”死胡同“,将每次要排排列的一个位序作为”岔路口“。
要点:
每次到岔路口时,需要回顾之前没选择的数字,查看每个数字是否被选择,因此设置一个hash表存放每个数字的使用情况。
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
int n, cnt;
void DFS(bool N[],int P[], int index){
if(index == n){
bool flag = true;
for(int i = 0; i < n - 1; i++){
for(int j = i + 1; j < n; j++){
if(abs(j - i) == abs(P[i] - P[j])){
flag = false;
break;
}
}
}
if(flag){
cnt++;
for(int i = 0; i < n; i++){
cout << P[i];
if(i != n - 1){
cout << ' ';
}else{
cout << '\n';
}
}
}
}
for(int i = 1; i <= n; i++){
if(!N[i]){
N[i] = true;
P[index] = i;
DFS(N, P, index + 1);
N[i] = false;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
while(cin >> n){
bool N[11];
int P[10];
memset(N, 0, sizeof(N));
cnt = 0;
DFS(N, P, 0);
if(!cnt){
cout << "no solute!\n";
}
}
return 0;
}