引言:下午復習算法時,越看越沒有信心,尤其是在看到比較抽象的舍伍德算法。感覺看了半天都還沒有弄明白該算法的意義在哪?更別談怎么用,都準備放棄了,想象放棄等于今天下午又什么事都沒有做,于是將舍伍德算法先放下,繼續后面的復習,看到拉斯維加斯和回朔法一起求解N后問題;開始提及該算法時,真的是挺恐懼的,但真正自己講代碼敲下來之后,瞬間思路清晰了許多;下面將具體的求解過程做如下筆記,方便以后復習:
一:問題描述:
二:解決辦法:
直接上代碼:
package Nquene;
/**
* 使用回朔法求解N后問題
* @author 陳鵬
*
*/
public class huishuo {
private static int[][] cheese;
private static final int N = 8;
public static int count = 0;
/**
* 初始化棋盤
*/
public huishuo(){
cheese = new int[N][N];
for(int i =0 ;i<N;i++){
for(int j = 0;j<N;j++){
cheese[i][j] = 0;
}
}
}
public static void putQueenAtRow(int row,int[][] cheese){
/**
* 遞歸終止條件
* 如果N等于8
* 表示已經找到了合適的棋盤位置
*/
if(N==row){
count++;
System.out.println("找到"+count+"合適的解了");
for(int i =0 ;i<N;i++){
for(int j = 0;j<N;j++){
System.out.print(cheese[i][j]+" ");
}
System.out.println();
}
return;
}
//臨時數組:clone只是在克隆引用;
int[][] temp = cheese.clone();
for(int i=0;i<N;i++){
//安全起見:每次放置第N行數據之前先將該行數據清空;
for(int j=0;j<N;j++){
temp[row][j] = 0;
}
temp[row][i] = 1;
if(isSafety(temp,row,i)){
putQueenAtRow(row+1,temp);
}
}
}
/**
* 判斷我們將要放置皇后的位置是否安全;
* @param arr 臨時棋盤
* @param row 行數
* @param col 列數
* @return
*/
public static boolean isSafety(int[][] arr,int row,int col){
//初始步伐為1;
int step = 1;
//終止條件為判斷到第一行時
while(row-step>=0){
//判斷直上方
if(arr[row-step][col]==1){
return false;
}
//判斷左上方:注意等號:=表示相鄰
if(col-step>=0 && arr[row-step][col-step]==1){
return false;
}
//判斷右上方:注意不要等號;
if(col+step<N && arr[row-step][col+step]==1){
return false;
}
step++;
}
return true;
}
public static void main(String[] args) {
huishuo temp = new huishuo();
huishuo.putQueenAtRow(0,cheese);
}
}