八个皇后

<pre name="code" class="java">八皇后问题是十九世纪著名数学家高斯于1850年提出的。问题是:在8*8的棋盘上摆放8个皇后,使其不能互相攻击,即任意的两个皇后不能处在同意行,同一列,或同意斜线上。可以把八皇后问题拓展为n皇后问题,即在n*n的棋盘上摆放n个皇后,使其任意两个皇后都不能处于同一行、同一列或同一斜线上。

public class EightQueues {
	private final int size;// 棋盘的大小,也表示皇后的数目
	private int[] location;// 皇后在期盼的每行上的列的位置
	private int[] colsOccupied;// 皇后在棋盘上占据的列
	private int[] cross1Occupied;// 皇后在棋盘上占据的反正对角线
	private int[] cross2Occupied;// 皇后在棋盘上占据的反对角线
	private static int count;// 解决方案个数
	private static final int STATUS_OCCUPIED = 1;// 占领
	private static final int STATUS_OCCUPY_CANCELED = 0;// 未占领
	public EightQueues(int size)// 初始化
	{
		this.size = size;
		location = new int[size];
		colsOccupied = new int[size];
		cross1Occupied = new int[2 * size];
		cross2Occupied = new int[2 * size];

	}
	public void printLocation() {
		System.out.println("一下是皇后在棋盘上的第" + count + "种摆放位置");
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++) {
				if (j == location[i])
					System.out.print('Q');
				else
					System.out.print('.');
			}

			System.out.println();
		}
	}
	private boolean isOccupied(int i, int j)// 判断位置(i,j)是否被占领
	{
		return (colsOccupied[j] == STATUS_OCCUPIED)
				|| (cross1Occupied[i - j - 1 + size] == STATUS_OCCUPIED)
				|| (cross2Occupied[i + j] == STATUS_OCCUPIED);
	}
	private void setStatus(int i, int j, int flag)// 如果flag为1,表示占领位置(i,j),否则表示取消占领
	{
		location[i] = j;
		colsOccupied[j] = flag;// 宣布占领或取消占领第j列
		cross1Occupied[i - j - 1 + size] = flag;// 宣布占领或取消占领正对角线
		cross2Occupied[i + j] = flag;// 宣布占领或取消占领反对角线
	}
	public void place(int i)// 从第i行开始摆放皇后
	{
		for (int j = 0; j < size; j++)// 在第i行分别尝试把皇后放在每一列上
		{
			if (!isOccupied(i, j))// 判断该位置是否被占领
			{

				setStatus(i, j, STATUS_OCCUPIED);// 宣布占领位置(i,j)
				if (i < size - 1)
					place(i + 1);// 如果所有皇后没有摆完,递归摆放下一行的皇后
				else {
					count++;// 统计解决方案的个数
					printLocation();// 完成任务,打印所有皇后的位置
				}
				setStatus(i, j, STATUS_OCCUPY_CANCELED);// 回溯,撤销占领位置(i,j)
			}
		}
	}
	public void start() {
		place(0);// 从第0行开始放置皇后
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new EightQueues(8).start();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值