n皇后问题(dfs)

n皇后问题

  1. 问题:
    请设计一种算法,解决著名的n皇后问题。这里的n皇后问题指在一个n*n的棋盘上放置n个棋子,
    使得每行每列和每条对角线上都只有一个棋子,求其摆放的方法数。
    给定一个int n,请返回方法数,保证n小于等于15

  2. 分析:
    画图,首先我们在第一行选择一列放入第一个皇后,然后在第二行,选择一列放入一个皇后,放入前需要判断,该列是否和前面的行在题意上冲突,如果冲突则换一列摆放,同意要检查。最终若最后一行能把最后一个皇后放进去则方法数加1。

  3. 代码(java):

import java.util.Scanner;
/**
 * 请设计一种算法,解决著名的n皇后问题。这里的n皇后问题指在一个n*n的棋盘上放置n个棋子,
 * 使得每行每列和每条对角线上都只有一个棋子,求其摆放的方法数。

 给定一个int n,请返回方法数,保证n小于等于15
 */
public class SelfDo {
	static int cnn=0;
	
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int []a=new int [n];
		dfs(a,0);//处理第0行,数组下标代表行,值代表列;
		System.out.println(cnn);
	}

	private static void dfs(int[] a, int i) {
		if(i==a.length) {
			cnn++;
			return;
		}
		for(int k=0;k<a.length;k++) {
			if(check(a,i,k)) {	//剪枝
				a[i]=k;
				dfs(a,i+1);
				a[i]=0;
			}
		}
		
	}

	private static boolean check(int[] a, int i, int k) {//检查第i行第k列放皇后合不合适
		for(int j=0;j<i;j++) {	//GG:j<a.length
			if(k==a[j]||j-a[j]==i-k||j+a[j]==i+k)//只和已经确定的状态作比较,只比较前态!
				return false;
		}
		return true;
	}
  1. 注意:
    1. 剪枝(条件判断)是dfs的难点。我们的数组默认值是0,也就是说,数组初始时是把所以的皇后都放在了第一列,因此判断时,一旦把某行在第0列放皇后,则一定会与后面所以值未定的行同出第0列导致判断为false。其实,我们的check函数,也只是用作与前面已经摆放的皇后的位置作比较,以确定当前位置是否可行。
    2. 如何判断二维数组(i,j)位置的对角线上是否有皇后——找数组下标的规律(位于同一主对角线上的下标横纵坐标之差与i-j之差一致;位于同一副对角线上的下标横纵坐标之和与i+j之和一致。)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值