java 回溯法求解 8皇后问题

18 篇文章 0 订阅
7 篇文章 0 订阅

 

package endual;

public class Queen {

	private final int size = 8;           // 棋盘的大小
	private int[] location ;              //皇后在棋盘上的每一行的列的位子
	private int[] colsOccupied ;          //皇后在棋盘上占据的列
	private int[] cross1Occuptied ;       //皇后在棋盘上占据的正对角线
	private int[] cross2Occuptied ;       //皇后在棋盘上占据的是反对角线
	private static int count ;       //解决的方法的个数
	
	
	
	private static final int STATUS_OCCUPIED = 1 ; //占据的状态
	private static final int STATUS_OCCUPY_CANCELED = 0 ; //没有占据的状态
	
	public Queen() {

		this.location = new int[this.size];
		this.colsOccupied = new int[this.size];
		this.cross1Occuptied = new int[2*this.size];
		this.cross2Occuptied = new int[2*this.size];
	}
	
	public void printLocation() {
		
		System.out.println("以下是皇后在棋盘上的第" +count+"种方式的摆放");
		for (int i=0; i <this.size; i++) {
			
			System.out.println("行:" + i + " 列:" + this.location[i]) ;
		}
	} //end 打印
	
	/*判断位子(i,j)是否被占领了*/
	private boolean isOccupied(int i, int j) {
	
		if(this.colsOccupied[j] == 1) {
			return true ;
		}
		
		if(this.cross1Occuptied[i-j+this.size-1] == 1) {
          return true ;
		}
		
		if (this.cross2Occuptied[i+j] == 1) {
			return true ;
		}
		
		return false ;
	}
	
	/**
	 * 如果flag为1,表示占领位子(i,j);
	 * 如果flag为0,表示取消占领位子(i,j) ;
	 */
	
	private void setStatus(int i, int j, int flag){
		
		this.colsOccupied[j] = flag ; //宣布占领或者是取消占领第j列
		this.cross1Occuptied[i-j+this.size-1] = flag ; //宣布占领或者取消占领正对角线
		this.cross2Occuptied[i+j] = flag ;    // 宣布占领或取消占领反对角
		

	}
	
	/**第一行开始摆放皇后**/
	public void place(int i) {
		
		for (int j=0; j < this.size; j++) { //在第i行尝试把皇后放在每一列
			
			if (!this.isOccupied(i, j)) { //判断该位子是不是已经被占领了的
				
				this.location[i] = j ; //摆放皇后,在第i行把皇后放在第j列
				this.setStatus(i, j, this.STATUS_OCCUPIED) ; //已经被占领了的
				
				if (i < this.size-1) {
					this.place(i+1) ;
					
				}else {
					this.count++ ;
					this.printLocation() ;
				}
				//回溯法
				this.setStatus(i, j, STATUS_OCCUPY_CANCELED) ;
				
			}

		}

	}

	public void start() {
		
		this.place(0) ;
	}
	
}

 

 测试的

 

package endual;

/**
 * 八皇后问题是一个古来而著名的问题,该问题是19世纪著名的数学家高斯同学提出来的。在8*8的国际象棋
 * 上摆放八个皇后,使其不能互相的攻击,也就是说,任意的两个皇后不能放在同一行或则是同一个列或者是
 * 同一个对角线上,问有多少个摆放的方法
 * @author Endual
 *
 *
 *
 */

public class MainApp {
	
	public static void main(String[] args) {
		
		Queen queen = new Queen() ;
		queen.start(); 

	}

} 

 

  要不来看下结果吧:部分的

 

 

以下是皇后在棋盘上的第1种方式的摆放
行:0 列:0
行:1 列:4
行:2 列:7
行:3 列:5
行:4 列:2
行:5 列:6
行:6 列:1
行:7 列:3
以下是皇后在棋盘上的第2种方式的摆放
行:0 列:0
行:1 列:5
行:2 列:7
行:3 列:2
行:4 列:6
行:5 列:3
行:6 列:1
行:7 列:4
以下是皇后在棋盘上的第3种方式的摆放
行:0 列:0
行:1 列:6
行:2 列:3
行:3 列:5
行:4 列:7
行:5 列:1
行:6 列:4
行:7 列:2
以下是皇后在棋盘上的第4种方式的摆放
行:0 列:0
行:1 列:6
行:2 列:4
行:3 列:7
行:4 列:1
行:5 列:3
行:6 列:5
行:7 列:2
以下是皇后在棋盘上的第5种方式的摆放
行:0 列:1
行:1 列:3
行:2 列:5
行:3 列:7
行:4 列:2
行:5 列:0
行:6 列:6
行:7 列:4
以下是皇后在棋盘上的第6种方式的摆放
行:0 列:1
行:1 列:4
行:2 列:6
行:3 列:0
行:4 列:2
行:5 列:7
行:6 列:5
行:7 列:3
以下是皇后在棋盘上的第7种方式的摆放
行:0 列:1
行:1 列:4
行:2 列:6
行:3 列:3
行:4 列:0
行:5 列:7
行:6 列:5
行:7 列:2
以下是皇后在棋盘上的第8种方式的摆放
行:0 列:1
行:1 列:5
行:2 列:0
行:3 列:6
行:4 列:3
行:5 列:7
行:6 列:2
行:7 列:4
以下是皇后在棋盘上的第9种方式的摆放
行:0 列:1
行:1 列:5
行:2 列:7
行:3 列:2
行:4 列:0
行:5 列:3
行:6 列:6
行:7 列:4
以下是皇后在棋盘上的第10种方式的摆放
行:0 列:1
行:1 列:6
行:2 列:2
行:3 列:5
行:4 列:7
行:5 列:4
行:6 列:0
行:7 列:3
以下是皇后在棋盘上的第11种方式的摆放
行:0 列:1
行:1 列:6
行:2 列:4
行:3 列:7
行:4 列:0
行:5 列:3
行:6 列:5
行:7 列:2
以下是皇后在棋盘上的第12种方式的摆放
行:0 列:1
行:1 列:7
行:2 列:5
行:3 列:0
行:4 列:2
行:5 列:4
行:6 列:6
行:7 列:3
以下是皇后在棋盘上的第13种方式的摆放
行:0 列:2
行:1 列:0
行:2 列:6
行:3 列:4
行:4 列:7
行:5 列:1
行:6 列:3
行:7 列:5
 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值