全排列
#include<iostream>
using namespace std;
const int maxn = 11;
int n, output[maxn], hashTable[maxn] = {false};
void generate(int index){
if(index == n){
for (int i = 0; i < n;i++){
cout << output[i];
}
cout << endl;
return;
}
for (int i = 1; i <= n;i++){
if(hashTable[i]==false){
output[index] = i;
hashTable[i] = true;
generate(index + 1);
hashTable[i] = false;
}
}
}
int main(){
n = 3;
generate(0);
return 0;
}
n皇后问题
n * n的棋盘上有n个棋子,任意两个棋子之间不在同一行,同一列或者同一对角线。
1.暴力全排列
考虑到每一列必有且仅有一颗棋子,所以棋子的行序号构成一个全排列,利用最后得到的全排列判断对角线情况即可判断该种情况是否成立。
2.回溯全排列
其实每种情况是否成立在摆放前几颗棋子时就已经出来结果了,所以提前判断一下,直接返回上一层,这种方法叫做回溯。
#include<cmath>
using namespace std;
const int maxn = 11;
int n, output[maxn], hashTable[maxn] = {false};
int count = 0;
void generate(int col){
if(col == n + 1){
count++;
return;
}
for (int i = 1; i <= n;i++){
bool flag = false;
if(hashTable[i]==false){
for(int j = 1;j<col;j++){
if(abs(output[j]-i)==abs(j-col)) {
flag = true;
break;
}
}
if(flag) continue;
output[col] = i;
hashTable[i] = true;
generate(col + 1);
hashTable[i] = false;
}
}
}
int main(){
n = 8;
generate(1);
cout<<count;
return 0;
}