/*八皇后問題
* 描述:在一個8*8的棋盤格上面放置八個皇后,使得每個皇后不能互相攻擊
* 攻擊:不能位於同一列,同一行,和對角線上
* 分析:一共有八行八列,則每一行每一列只能有一個皇后
*/
/*
* 判斷給定的位置是否安全
* 參數爲已經確定的點的數組,和要進行判斷的點的行和列座標
*/
private static boolean safeLocation(int [] queues,int row,int col){
for(int i =0 ; i <col ; i++){
//判斷是否會攻擊
if( (i == col) || (queues[i] == row) || ( (row+col) ==(i+queues[i]) ) || ( (queues[i]-i) == row-col ) ){
return false;
}
}
return true;
}//end safeLocation
/*
* 八皇后問題算法實現
* 採用回溯的策略來實現,如果遞歸的過程中遇到錯誤,則返回上一層遞歸
* 重新選擇上一步的位置
*/
public boolean eightQueue(int[] queues,int col){
int row; //記錄行數
boolean foundLocation; //標記遞歸是否可以得到正確的位置
//結束遞歸調用條件,如果列數等於8則結束
if(col == 8){
foundLocation = true;
}
else{
row = 0;
foundLocation = false;
//回溯算法如果,遞歸調用的子調用的結果爲false則返回該函數繼續判斷,
//找到合適的點再次調用遞歸。
while(row < 8 && foundLocation != true){
if(safeLocation(queues, row, col)){
queues[col] = row;
foundLocation = eightQueue(queues, col+1);
if(!foundLocation){
row++;
}
}
else{
row++;
}
}
}//end else
return foundLocation;
}//end eightQueue
/*
* 測試驅動
* 指定初始的行數
*/
public boolean startEightQueue(int queues[],int row){
//指定第一列的初始行數
queues[0] = row;
if(eightQueue(queues, 1)){
return true;
}
else{
return false;
}
}//end startEightQueue
<pre name="code" class="java">//完整實現
package 算法;
import java.awt.Button;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import 排序.bubble;
/*八皇后問題
* 描述:在一個8*8的棋盤格上面放置八個皇后,使得每個皇后不能互相攻擊
* 攻擊:不能位於同一列,同一行,和對角線上
* 分析:一共有八行八列,則每一行每一列只能有一個皇后
*/
public class EightQueue {
/*
* 判斷給定的位置是否安全
* 參數爲已經確定的點的數組,和要進行判斷的點的行和列座標
*/
private static boolean safeLocation(int [] queues,int row,int col){
for(int i =0 ; i <col ; i++){
//判斷是否會攻擊
if( (i == col) || (queues[i] == row) || ( (row+col) ==(i+queues[i]) ) || ( (queues[i]-i) == row-col ) ){
return false;
}
}
return true;
}//end safeLocation
/*
* 八皇后問題算法實現
* 採用回溯的策略來實現,如果遞歸的過程中遇到錯誤,則返回上一層遞歸
* 重新選擇上一步的位置
*/
public boolean eightQueue(int[] queues,int col){
int row; //記錄行數
boolean foundLocation; //標記遞歸是否可以得到正確的位置
//結束遞歸調用條件,如果列數等於8則結束
if(col == 8){
foundLocation = true;
}
else{
row = 0;
foundLocation = false;
//回溯算法如果,遞歸調用的子調用的結果爲false則返回該函數繼續判斷,
//找到合適的點再次調用遞歸。
while(row < 8 && foundLocation != true){
if(safeLocation(queues, row, col)){
queues[col] = row;
foundLocation = eightQueue(queues, col+1);
if(!foundLocation){
row++;
}
}
else{
row++;
}
}
}//end else
return foundLocation;
}//end eightQueue
/*
* 測試驅動
* 指定初始的行數
*/
public boolean startEightQueue(int queues[],int row){
//指定第一列的初始行數
queues[0] = row;
if(eightQueue(queues, 1)){
return true;
}
else{
return false;
}
}//end startEightQueue
/*
* 在圖形界面顯示八皇后問題的結果
*/
public void showInPanel(int [] queues){
JFrame frame = new JFrame("八皇后");
GridLayout layout = new GridLayout(8,8,0,2);
frame.setLayout(layout);
ArrayList<Button> button = new ArrayList<Button>();
for(int i = 0 ; i < 64 ;i++){
button.add(new Button(" "));
//frame.add(button.get(i));
}
for(int i =0 ; i < 8; i++){
Button bu = new Button("8");
bu.setBackground(Color.GREEN);
button.set(i+queues[i]*8, bu);
}
for(Button b: button){
frame.add(b);
}
frame.setSize(400, 400);
frame.setVisible(true);
}
/*
*在命令行中顯示結果
*/
public void showOnConsole(int [] queues){
int [] [] end = new int[8][8];
for(int i =0 ; i < 8;i++){
end[queues[i]][i] =1;
}
for(int m =0 ; m < 8; m++){
for(int n = 0 ; n< 8 ; n++){
if(end[m][n] != 0){
System.out.print("| 8 ");
break;
}
else{
System.out.print("| 0 ");
}
}
System.out.println(" |");
}
}
public static void main(String[] args) {
int queues[] = new int [8];
EightQueue e = new EightQueue();
Scanner sc = new Scanner(System.in);
System.out.println("請輸入起始的行(1~8):");
int col = sc.nextInt();
if(col < 1 ||col >8){
throw new IllegalArgumentException("請輸入正確的選項");
}
e.startEightQueue(queues,col-1);
System.out.println("選擇顯示的方式:1、命令行 2、圖形界面 3、1和2:");
int choice = sc.nextInt();
switch(choice){
case 1:
e.showOnConsole(queues);
break;
case 2:
e.showInPanel(queues);
break;
case 3:
e.showOnConsole(queues);
e.showInPanel(queues);
break;
default :
System.err.println("請輸入正確的選擇:");
break;
}
}//end main
}