八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。
题解是看别人的:https://blog.youkuaiyun.com/codes_first/article/details/78474226
这道题确实很经典,通过这道题对递归的理解有加深了一个层次,时刻想象把递归当成很多个for循环来做题,想要理解递归,还是要自己多看看代码,多写写代码,原理看得懂,代码不一定写的出,看别人代码看懂了,自己不一定能在写出来。
#include <iostream>
#include <vector>
using namespace std;
vector<int> queen(8,-1);
int count = 0;
bool available(int row, int line) { //找row line是否合法
for(int i = 0; i < row; i++) {
if(queen[i] == line) return false; //如果从已经安排好的行数找的话,有相同的就返回false
if((line-queen[i]) == (row - i)) return false;//如果斜率等于一证明在同一条对角线上
if((line-queen[i])+(row - i) == 0) return false; //如果斜率等于负一证明也在同一条对角线上
}
return 1;//满足条件返回true
}
void solve(int row) {
for(int i = 0; i < 8; i++) { //找到一个可以放皇后的位置
if(available(row, i)) {
queen[row] = i; //记录下这一行的位置,每一个i都会更新queen,所以不用考虑重置它的值是多少
if(row == 7) { //如果到了最后一行 这种方案啊可以实行
count++;
return;
}
solve(row+1); //把递归看成很多个for循环 找到就跳出循环 ******************
} //递归就是这样暴力搜索
}
return;
}
int main() {
solve(0); //从一行开始找
cout << count ;
return 0;
}
。