八皇后问题WIKI: http://zh.wikipedia.org/wiki/%E5%85%AB%E7%9A%87%E5%90%8E%E9%97%AE%E9%A2%98
参考:
1. http://zhedahht.blog.163.com/blog/static/2541117420114331616329/
2. http://www.datagenetics.com/blog/august42012/
3.http://blog.csdn.net/hackbuteer1/article/details/6657109
key point:
由于八个皇后的任意两个不能处在同一行,那么这肯定是每一个皇后占据一行。于是我们可以定义一个数组queen[8],数组中第i个数字表示位于第i行的皇后的列号。先把queen的八个数字分别用0-7初始化,接下来我们要做的事情就是对数组queen做全排列。由于我们是用不同的数字初始化数组中的数字,因此任意两个皇后肯定不同列。我们只需要判断得到的每一个排列对应的八个皇后是不是在同一对角斜线上,也就是数组的两个下标i和j,是不是|i-j|==queen[i]-queen[j](也就是说两个点的横坐标和纵坐标的差的绝对值是否相等)。
php实现并做benchmark:
<?php
/*
* @author:wusuopubupt
* @date:2013-09-12
*
* eight queens puzzle recursive solution with php
*/
$length = 8;
$queen = array ();
$sum = 0;
function print_queen() {
global $length;
global $queen;
global $sum;
++ $sum;
printf("Solution %d:\t",$sum);
for($i = 0; $i < $length; $i ++) {
printf ( "%d\t",$queen [$i] );
}
printf ( "\r\n" );
}
function is_safe($n) {
global $length;
global $queen;
for($i = 0; $i < $n; $i ++) {
if ($queen [$i] == $queen [$n] || ($queen [$i] - $queen [$n]) == ($n - $i)
|| ($queen [$i] - $queen [$n] == ($i - $n))) {
return false;
}
}
return true;
}
function eight_queens($n) {
global $length;
global $queen;
for($i = 0; $i < $length; $i ++) {
$queen [$n] = $i;
if (is_safe ( $n )) {
if ($n == $length - 1) {
print_queen ();
}
else {
eight_queens ( $n + 1 );
}
}
}
}
/*
* benchmark
*/
$starttime = microtime ( true );
eight_queens( 0 );
$endtime = microtime ( true );
printf ( "time spend: %.4f\n", $endtime - $starttime );
printf ("total solutions: %d",$sum);
返回截图:
运行一次,耗时0.0695秒;