八皇后在搜索中算是一个最经典的例题了,故本文亦可作为复习与巩固深度优先搜索的过程。
八皇后原题如下:
题意可看作在nn的棋盘中放入n个皇后,每个皇后既不能在同一行,同一列,亦不能在同一对角线上。显而易见,既然有n个皇后,那么每行有且仅能有一个皇后(否则将有皇后要与其他皇后同一行,不符合题意),那么似乎使用一个n层循环的枚举似乎也能解决这个问题,然而一个n层的循环不仅使程序看上去非常的繁琐,而且在实际上涉及大量细节处理问题,同时各个皇后相互影响并非循环枚举可以进行判断,故并不可取,既然有着所谓的“层数”又希望追求程序的精简,不妨用深度优先搜素(dfs)实现。
前面已经说了,既然要把n个皇后放在每一列,不妨就将行数作为函数的参数:每一层就是每一行,并在每一层对每一列进行枚举。(对每一个皇后位置的枚举)这样使得搜索的出口也非常明显,即当第n个皇后找到位置时,函数可以返回。
笔者认为出口与过程是搜索的核心(仅个人观点),因此构造搜索函数时请注意这两点,如本题中的出口即在第n个皇后找到位置时,过程是枚举每一列以确定当前皇后的位置
注:因为每次皇后的位置判断受到上一个皇后的影响,因此要对每次放置的皇后进行标记,当回到当前层时(搜索完当前列的所有内容)要解放标记(回溯)。同一对角线可用i+j(i-j)来表示(一条对角线上的每个点行与列的和或差相等)。
代码如下(输出66棋盘下的所有解):
int ans[100],a[100]