使用分治思想与递归解决八皇后问题

问题描述

在一个8*8的棋盘内插入8个皇后,使得任意两个不在同一行同一列以及对角线上。

解决思路

将大问题化解为小问题,小问题描述为,前i行已经插入i个皇后,现在第i+1行插入第i+i个皇后。则只需遍历第i+1行上的每一个单元格,并且判断该单元格是否能够插入皇后,若能够插入皇后则将皇后插入相应位置,然后以该棋盘为基础进行第i+2行插入第i+2个皇后的求解,直到i>8后,即表示前8个皇后都以插入棋盘,且没有冲突,此时找到解。

坐标类

package cn.queen;
//位置
public class Post {
	
	int x;
	int y;
	
	public Post(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}

	@Override
	public String toString() {
		return "("+x+","+y+")";
	}
		
}

棋盘类

package cn.queen;

import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

//棋盘
public class Chessboard {
	
	List<Post> queens;//存皇后位置
	int n;//棋盘尺寸
	
	public Chessboard(int n) {
		super();
		this.n = n;
		this.queens = new LinkedList<Post>();
	}
	//判断是否能在q位置上插入皇后
	public boolean canAdd(Post q) {
		ListIterator<Post> i = this.queens.listIterator();
		while (i.hasNext()) {
			Post p = i.next();
			//任意两个皇后不能在同一行,同一列和对角线上
			if(p.x == q.x||p.y == q.y||Math.abs(q.x-p.x)==Math.abs(q.y-p.y)) {
				return false;
			}
		}
		return true;
	}

	@Override
	public String toString() {
		return "Chessboard"+this.queens.toString();
	}
		
}

主类

package cn.queen;

/**
 * 解决八皇后问题采用分治的思想,将大问题化成若干小问题
 * 
 * */
public class MainClass {

	public static int n = 8;//棋盘尺寸
	public static Chessboard c = new Chessboard(n);
	public static int num = 0;//记录总数

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		trial(0);
	}
	
	public static void trial(int i) {
		if(i >= n) {//此时前i个皇后位置都以确定,表示n个皇后都以在棋盘内,找到解
			num++;
			System.out.println(num + "\t=  " + c);
			return;
		}
		for(int j = 0;j<n;j++) {//遍历第i行上的所有单元格
			Post p = new Post(i+1,j+1);
			if(c.canAdd(p)) {//判断在第i行第j列插入皇后时,是否会产生冲突
				//System.out.println(new Post(i,j));
				c.queens.add(p);//将该位置上插入棋盘
				trial(i+1);//因为该位置插入后不产生冲突,所以在此基础之上进行下一行的探索
				c.queens.remove(c.queens.size()-1);//进行下一个单元个的探索前,应删除刚刚插入的单元格
			}
		}
		
	}

}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值