八皇后问题(回溯法)
不考虑棋盘对称,共有92种方法
方法一:O(n2)
#include<stdio.h>
#include<iostream>
using namespace std;
int tot = 0,n = 8;
int C[8];
void search(int cur);
int main()
{
search(0);
cout<<tot;
}
void search(int cur) {
if(cur== n)
tot++;
else
for(inti = 0;i < n;i++) {
intok = 1;
C[cur]= i;
for(intj = 0;j < cur;j++)
if(C[cur]== C[j] || cur - C[cur] == j - C[j]
||cur + C[cur] == j + C[j])
{
ok= 0;
break;
}
if(ok)search(cur + 1);
}
}
注意:cur-C[cur] == j –C[j] || cur+ C[cur] == j + C[j]
用来判断(cur,C[cur])和(j,C[j])是否在同一条直线上
方法二:O(n)
#include<iostream>
using namespace std;
int vis[3][20];
int tot = 0,n = 8;
int C[8];
void search(int cur);
int main()
{
search(0);
cout<<tot;
}
void search(int cur) {
if(cur== n)
tot++;
else
for(inti = 0;i < n;i++) {
if(!vis[0][i]&& !vis[1][cur+i] && !vis[2][cur-i+n]) {
C[cur]= i;
vis[0][i]= vis[1][cur + i] = vis[2][cur - i + n] = 1;
search(cur+1);
vis[0][i]= vis[1][cur + i] = vis[2][cur - i + n] = 0;
}
}
}
利用vis数组作为一个状态数组,表示已经放置的皇后占据了哪些列,主对角线和副对角线(所以vis数组有3行)
注意:一般若在回溯法中使用全局变量,则在一定的时候要将其状态复原,谨记!!!
一般来说可以避免使用全局变量