您的位置:首页 > 其它

八皇后问题

2014-02-14 19:18 267 查看
今天成功加入了importNew翻译小组~就像面试成功了似的~

自己参照着严蔚敏的数据结构书实现了下八皇后问题,递归遍历打印出八皇后棋盘的的所有状态树~

以下是我写的源代码~不知道大家有没有更好的判断一个皇后与已有的皇后有没有冲突的算法呢?

package com.zk.ds;

/**
* 八皇后问题<br>
* 算法参见严蔚敏:数据结构(C语言版)P151页
* @author 1291700520@qq.com
*
*/
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();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: