n皇后问题

看剑指offer时,看到全排列算法,后面的扩展引申,说可以用此思路解决8皇后问题,我就改成了解决n皇后问题。

之前出现函数参数值传递还是引用传递问题,就是由于此代码出问题引发的思考。

代码如下:

public class QueenProblem {

	/*
	 * 不同行的皇后不能在同一列,且任意两个皇后不能在同一对角线上
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		QueenProblem question = new QueenProblem();
		int n = 4;
		int count = question.counOfQueenProblem(n);
		System.out.println(n + "皇后问题共有 "+ count + " 种解法。");
	}

	// 初始化皇后的位置
	// 譬如queens[i] = j,表示第i行的皇后在第j列
	//这种初始化保证了不同皇后不可能在同一行,而对于列值,只进行交换操作,保证了不同皇后不可能在同一列
	public int counOfQueenProblem(int numberOfQueens) {
		if (numberOfQueens < 4)
			return 0;
		else {
			int[] queens = new int[numberOfQueens];
			for (int i = 0; i < numberOfQueens; i++)
				queens[i] = i;

			return countsOfQueenPlace(queens, 0);
		}
	}

	public int countsOfQueenPlace(int[] queens, int index) {
		int count = 0;
		if (index == queens.length - 1) {
			boolean flag = true;
			for (int i = 0; i < queens.length; i++) {
				for (int j = 0; j < queens.length; j++) {
					if (i != j) {
						//判断是否有两个皇后在同一对角线上
						if (i - j == queens[i] - queens[j]
								|| j - i == queens[i] - queens[j]) {
							flag = false;
							break;
						}
					}
				}
				if (!flag)
					break;
			}

			if (flag) {
				printQueens(queens);
				count++;
			}
		} else {

			for (int i = index; i < queens.length; i++) {
				swap(queens, index, i);
				count += countsOfQueenPlace(queens, index + 1);
				swap(queens, i, index);
			}
		}

		return count;
	}

	void swap(int[] array, int index1, int index2) {
		int temp = array[index1];
		array[index1] = array[index2];
		array[index2] = temp;
	}

	void printQueens(int[] queens) {
		for (int i = 0; i < queens.length; i++) {
			for (int j = 0; j < queens[i]; j++) {
				System.out.print("*");
			}
			System.out.println("Q");
		}
		System.out.println("========================");
	}

}
下面是4皇后问题的输出结果:

*Q
***Q
Q
**Q
========================
**Q
Q
***Q
*Q
========================
4皇后问题共有 2 种解法。

只需要改变主函数中 n 的值,便可求出对应 n皇后问题 的解,篇幅有限,只展示下 4皇后问题的结果, 但是n值若是太大应该会出问题,毕竟是使用递归做的。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值