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);