n后问题

一、问题的描述

在n×n的国际象棋棋盘中放置彼此不受攻击的那个皇后,按照规则,如果n个皇后不互受攻击,则任何一个皇后不能跟其它皇后在棋盘的同一行或同一列,也不能在斜对角。

二、问题的分析

1,解的假设

自己可以动手画一个4*4的棋盘,然后将尝试将4个皇后放进棋盘,可以有两种解决方案:

      


显然,通过一步步尝试,解决该问题要用到回溯法,并且解的形式满足m叉树(还有另外两种是子集树和排列树),然后通过上述的限制条件剪去一些不满条件的枝(同行或同列,斜对角),问题的搜索空间深度为n(皇后的个数,严格的说应该是棋盘的列数,这里皇后的个数与期盼的列数相等)

2,确定解空间

a,根据上面的解的假设,可以定义解的形式为{x1,x2,…xi…,xn}其中xi表示在第i行xi的当前取值

b,满m叉树,深度为n

c,限制条件,n个皇后不互受攻击(不能同一列:xi != xt;不能是斜对角:|t - i| != |xt - xi|;t是用来控制深度搜索;这里无需考虑在同一行的情况

三、代码实现

本例使用java语言实现

public class TraceBack {

	final static int N = 8;
	static long sum = 0;
	static void print(int[] gezi) {
		for(int i = 1;i <= N;i++) {
			for(int j = 1;j <= N;j++) {
				if(gezi[i]!=j){
					System.out.print(" - ");
				}else{
					System.out.print(" " + gezi[i] + " ");
				}
			}
			System.out.println();
		}
		System.out.println();
	}
	
	//用于判断皇后位置是否合法
	static boolean place(int[] x,int t) {
		for(int i = 1;i < t;i++) {
			//斜对角或同列
			if(Math.abs(x[t] - x[i]) == Math.abs(t - i) || x[t] == x[i]) return false;
		}
		return true;
	}
	
	static void btrack(int[] x, int t) {
		if(t > N) {
			sum++;
			print(x);
		}
		else
			for(int i = 1;i <= N;i++) {
				x[t] = i;
				if(place(x,t)) btrack(x,t + 1);
			}
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//4×4的九宫格的回溯
		int[] x = new int[N + 1];
		btrack(x,1);
		System.out.println(TraceBack.sum);
	}

}


四,结果分析

将上述代码运行,发现当n = 8时,sum = 92;当n = 16时,结果就相当大了,运行半天还没有运行完!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值