递归-N皇后问题

1.PHP实现

 1 //N皇后
 2 //N皇后问题是指在N*N的棋盘上要摆N个皇后,要求
 3 //任何两个皇后不同行、不同列,也不在同一条直线上
 4 //给定一个证数n,返回n皇后的摆法有多少种
 5 
 6 function nQueen($n,$row=0,&$queen=[]){
 7    //
 8     if($row == $n){
 9         return 1;
10     }
11     $res = 0;
12     //对于同一行,遍历所有的列,找到符合条件的所有位置
13     for($col=0;$col<$n;$col++){
14         if(isValid($queen,$row,$col)){
15             $queen[$row] = $col;
16             $res +=  nQueen($n,$row+1,$queen);
17         }
18     }
19     return $res;
20 }
21 //验证位置是否可以放置皇后
22 function isValid($queen=[],$row,$col){
23     //$len = count($queen);
24     //判断[$row,$col]放置的皇后是否与假设冲突
25     for($i=0;$i<$row;$i++){
26         //如果在同一列、或在同一条对角线上
27         if($queen[$i]==$col||(abs($i-$row)==abs($queen[$i]-$col))){
28             return false;
29         }
30     }
31     return true;
32 }
33 
34 //方法二:
//$limit是一个由n位1构成的二进制数 35 //$colLimit是一个n位的二进制数,0的位置可以放皇后(列限制) 36 //$leftLimit是一个n位的二进制数,0的位置可以放皇后(左对角线限制) 37 //$rightLimit是一个n位的二进制数,0的位置可以放皇后(右对角线限制) 38 function nQueen2($limit,$colLimit,$leftLimit,$rightLimit){ 39 40 if($colLimit==$limit) 41 return 1; 42 $pos = $limit & (~($colLimit|$leftLimit|$rightLimit)); 43 $mostRightOne = 0; 44 $res = 0; 45 while($pos!=0){ 46 //取出最右边的1的位置 47 $mostRightOne = $pos & (~$pos +1); 48 $pos = $pos - $mostRightOne; 49 $res += nQueen2($limit,$colLimit|$mostRightOne,($leftLimit|$mostRightOne)<<1,($rightLimit|$mostRightOne)>>1); 50 } 51 return $res; 52 } 53 54 $n = 5; 55 //$arr = array_fill(0,$n,1); 56 $queen=[]; 57 $res = nQueen($n,0,$queen); 58 print($res); 59 print(" "); 60 print_r($queen); 61 62 $limit = (1<<$n)-1; 63 $res2 = nQueen2($limit,0,0,0); 64 print(" "); 65 print($res2);
原文地址:https://www.cnblogs.com/indifferent/p/14400454.html