n后问题

来源:互联网 发布:淘宝店铺女装名字大全 编辑:程序博客网 时间:2024/05/16 06:14

一、问题的描述

在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);}elsefor(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时,结果就相当大了,运行半天还没有运行完!

原创粉丝点击