您的位置:首页 > 编程语言 > Java开发

N皇后问题的Java实现

2017-07-21 23:18 363 查看
回溯法求解,

package com.junoflo;

/**
* Created by Administrator on 2017/7/21.
*/
public class FourQueen {
private static int size = 4;
private static int [][]board = new int[size][size];
private static int [][]tmp = new int[size][size];//输出有重复的,做一下去重
private static int legalBoardCount = 0;
public static void showBoard(){
if(isSameBoard(board,tmp))
return;
System.out.println("board bellow...");
for (int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
System.out.print(board[i][j] + " ");
tmp[i][j] = board[i][j];
}
System.out.println();
}
legalBoardCount++;
}
public static void setChess(int posX,int posY){
if(posX >= size || posY >= size)
return;
board[posX][posY] = 1;
}
public static void takeChess(int posX,int posY){
if(posX >= size || posY >= size)
return;
board[posX][posY] = 0;
}

/**
* X 方向的棋子是否合法
* @param y
* @return
*/
public static boolean chessOnX(int y){
int count = 0;
for(int i = 0; i < size; i++){
if(board[i][y] == 1)
count++;
}
return count > 1;
}

/**
* Y 方向的棋子是否合法
* @param x
* @return
*/
public static boolean chessOnY(int x){
int count = 0;
for(int j = 0; j < size; j++){
if(board[x][j] == 1)
count++;
}
return count > 1;
}
public static boolean isSameBoard(int[][]board1,int [][]board2){
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
if(board1[i][j] != board2[i][j])
return false;
}
}
return true;
}
/**
* 左边所有斜线是否合法(即斜率为负)
* @return
*/
public static boolean chessOnDiagonalLeft(){
//先找左下角部分
int x = size - 1,y = 0;
do{
int count = 0;
for(int i = x,j = y; i > -1 && j > -1; i--,j--){
if(board[i][j] == 1)
count++;
}
if(count > 1)
return false;
}while (++y < size);
//找右上角部分
x = 0; y = size - 1;
do{
int count = 0;
for(int i = x,j = y; i < size && j < size; i++,j++){
if(board[i][j] == 1)
count++;
}
if(count > 1)
return false;
}while (--y > -1);
return true;
}

/**
* 右边所有斜线是否合法(即斜率为正)
* @return
*/
public static boolean chessOnDiagonalRight(){
//先找右下角
int x = 0,y = 0;
do{
int count = 0;
for(int i = x,j = y; i < size && j > -1; i++,j--){
if(board[i][j] == 1)
count++;
}
if(count > 1)
return false;
}while (++y < size);
//再找左上角
x = size - 1; y = size - 1;
do{
int count = 0;
for(int i = x, j = y; i > -1 && j < size; i--,j++){
if(board[i][j] == 1)
count++;
}
if (count > 1)
return false;
}while (--y > -1 );
return true;
}

public static boolean isLegal(){
if(!chessOnDiagonalLeft() || !chessOnDiagonalRight())
return false;
int x = 0, y = 0;
do{
if(chessOnX(y) || chessOnY(x))
return false;
}while (++x < size && ++y < size);
return true;
}
//核心,递归求解
//参数 i 代表在此之前的i行有i个棋子被正确摆放,初始入参为0
//现从i+1行开始为后续棋子选择合适的位置
public static void trial(int i,int n){
if(i > n) showBoard();
else for (int j = 0; j < n; j++){
setChess(i,j);
if(isLegal()){
trial(i+1,n);
}
takeChess(i,j);
}
}
public static void main(String[] args) {
//初始 i = 0
trial(0,size);
System.out.println(size + "皇后问题有 " + legalBoardCount + " 个解");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  N皇后 回溯法 Java