n皇后问题(回溯法)

问题:

在n×n格的国际象棋上摆放n个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法?

分析:

乍一看n*n似乎需要一个二维数组,实际上一个一维数组就足够了,例如rec[x]=y;
其中x就是横坐标,y就是纵坐标。
这边讲解的是中规中矩的回溯法。

回溯法:步步深入试探,若无果,返回上一级重新选择,这就是回溯法。(感觉像深搜的剪枝)

大致思路

就是回溯的思路,只不过在判定条件上比较麻烦的是需要判定斜线上是否相同。
左斜线:每一个点的x坐标和y坐标相减的值都相同,
右斜线:每一个点的x坐标和y坐标相加的值相同,
如下图:(虽然是手敲的)
1,1 1,2 1,3
2,1 2,2 2,3
3,1 3,2 3,3
左斜线:1-1=2-2=3-3
右斜线:1+3=2+2=3+1
:因为是一维数组下标不可能相同所以不可能在同一行,
:是否在同一列只需要判断每一个下标对应的值是否相等就行了。
有了这个结论我们就可以以此写判断条件

以下是代码

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Scanner;

public class _15dfsn皇后问题 {
	static int[] rec;//一维数组
	static int row;//行
	static int cnt;//列

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);//
		row = sc.nextInt();
		rec = new int[row];
		cnt = 0;
		dfs(0);
		System.out.println(cnt);//输出结果
	}

	static void dfs(int r) {
		if (r == row) { //求出一组解,cnt+1
			cnt++;
			return;
		}
		for (int col = 0; col < row; col++) {//试探每一个列是否能否放置皇后
			boolean ok = true;
			for (int j = 0; j < r; j++) {//遍历之前每一个皇后位置
				if (rec[j] == col || rec[j] + j == col + r || rec[j] - j == col - r) {//是否和当前皇后在同一斜线或者同一列
					ok = false;
					break;
				}
			}
			if (ok) {//如果当前点可放置,则继续下一个节点的探查
				rec[r] = col;//记录列
				dfs(r + 1);
				rec[r] = 0;//可写可不写反正开始新的一组判定时会重新赋值
			}
		}
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值