今天成功加入了importNew翻譯小組~就像面試成功了似的~
自己參照着嚴蔚敏的數據結構書實現了下八皇后問題,遞歸遍歷打印出八皇后棋盤的的所有狀態樹~
以下是我寫的源代碼~不知道大家有沒有更好的判斷一個皇后與已有的皇后有沒有衝突的算法呢?
package com.zk.ds;
/**
* 八皇后問題<br>
* 算法參見嚴蔚敏:數據結構(C語言版)P151頁
* @author [email protected]
*
*/
public class EightQueensProblem {
/**
* 模擬棋盤,false表示此處沒有皇后,true代表此處有皇后
*/
private static boolean[][] eightQueens = {
{false, false, false, false, false, false, false, false},
{false, false, false, false, false, false, false, false},
{false, false, false, false, false, false, false, false},
{false, false, false, false, false, false, false, false},
{false, false, false, false, false, false, false, false},
{false, false, false, false, false, false, false, false},
{false, false, false, false, false, false, false, false},
{false, false, false, false, false, false, false, false},
};
/**
* 統計個數
*/
private static int count = 0;
public static void main(String args[]){
trial(0, eightQueens.length);
}
/**
* 探測棋盤
* @param i 當前探測的是棋盤的第幾行的索引 i = [0,1,2,...]
* @param n n皇后
*/
public static void trial(int i, int n){
if(i >= n){ /*如果所有行檢查完畢*/
System.out.println("--------------" + ++count + "----------------");
printQueens(eightQueens);
}else{
for(int j=0; j<n; ++j){
eightQueens[i][j] = true; /*進行試探,在eightQueens[i][j]處新放置一個皇后*/
if(isQueenAvailble(i, j, eightQueens)){ /*如果eightQueens[i][j]不衝突,則繼續探測,直至打印*/
trial(i + 1, n);
}
eightQueens[i][j] = false;/*如果eightQueens[i][j]衝突,那麼將此皇后移走*/
}
}
}
/**
* 如果eightQueens[row][col]處放置一個新的皇后,檢測是否有皇后衝突<br>
* @param row 新放置的皇后的row
* @param col 新放置的皇后的col
* @param eightQueens 棋盤
* @return 衝突返回false,不衝突返回true
*/
private static boolean isQueenAvailble(int row, int col, boolean[][] eightQueens){
return isRowAvailable(row, col, eightQueens) && isColAvailable(row, col, eightQueens)
&& isRightSkewAvailable(row, col, eightQueens)
&& isLeftSkewAvailable(row, col, eightQueens);
}
/**
* 如果eightQueens[row][col]處放置一個新的皇后,檢測橫線上是否有皇后衝突<br>
* @param row 新放置的皇后的row
* @param col 新放置的皇后的col
* @param eightQueens 棋盤
* @return 衝突返回false,不衝突返回true
*/
private static boolean isRowAvailable(int row, int col, boolean[][] eightQueens){
for(int j=0; j<eightQueens.length; ++j){
if(eightQueens[row][j] && j != col){
return false;
}
}
return true;
}
/**
* 如果eightQueens[row][col]處放置一個新的皇后,檢測豎線上是否有皇后衝突<br>
* @param row 新放置的皇后的row
* @param col 新放置的皇后的col
* @param eightQueens 棋盤
* @return 衝突返回false,不衝突返回true
*/
private static boolean isColAvailable(int row, int col, boolean[][] eightQueens){
for(int i=0; i<eightQueens.length; ++i){
if(eightQueens[i][col] && row != i){
return false;
}
}
return true;
}
/**
* 如果eightQueens[row][col]處放置一個新的皇后,檢測右對角線上是否有皇后衝突<br>
* @param row 新放置的皇后的row
* @param col 新放置的皇后的col
* @param eightQueens 棋盤
* @return 衝突返回false,不衝突返回true
*/
private static boolean isRightSkewAvailable(int row, int col, boolean[][] eightQueens){
int rows = eightQueens.length;
int whichMin = (row <= col) ? -row : -col;
int whichMax = (rows - row) <= (rows - col) ? (rows - row) : (rows - col);
for(int i=whichMin; i<whichMax; ++i){
if(eightQueens[row + i][col + i]){
if(i != 0){
return false;
}
}
}
return true;
}
/**
* 如果eightQueens[row][col]處放置一個新的皇后,檢測左對角線上是否有皇后衝突<br>
* @param row 新放置的皇后的row
* @param col 新放置的皇后的col
* @param eightQueens 棋盤
* @return 衝突返回false,不衝突返回true
*/
private static boolean isLeftSkewAvailable(int row, int col, boolean[][] eightQueens){
int maxIndex = eightQueens.length - 1;
int leftOffset = 0;
int rightOffset = 0;
if(row + col <= maxIndex){/*所探測的點位於左上半部分*/
leftOffset = -col;
rightOffset = row;
}else{/*所探測的點位於右下半部分*/
leftOffset = row - maxIndex;
rightOffset = maxIndex - col;
}
for(int i=leftOffset; i<=rightOffset; ++i){
if(eightQueens[row - i][col + i] && i != 0){
return false;
}
}
return true;
}
/**
* 打印當前棋牌<br>
* [*]表示有皇后,[ ]表示無皇后
* @param eightQueens
*/
private static void printQueens(boolean[][] eightQueens){
for(boolean[] b1:eightQueens){
for(boolean b2:b1){
if(b2){
System.out.print("[*],");
}else{
System.out.print("[ ],");
}
}
System.out.println();
}
}
}