八皇后问题是一个很经典的算法问题。不知道八皇后是啥的同学。。。 可以略过了。
八皇后和四皇后是一样的,为了简单起见,下面先考虑四皇后:
首先,在4*4的方格内放4个皇后,他们相互不攻击,应该有一个基本的概念:如果有这么一种放皇后的方法,那么4个皇后肯定是每行一个,并且每列一个。这是最基本的。
其次,斜行怎么表示是皇后问题的一个比较重要的点。考虑一个四乘四的16个方格,第i行第j列,和第i+1行第j+1列,和第i+1行,第j-1列都是斜行。可以发现,对于从左上到右下的斜行,i-j是一个定值。对于右上到左下的斜行,i+j是定值,所以很自然的想到用一个容量为2*n的数组存储每一个方格的相应斜行是否可用。
想到怎么表现一个方格是否可用,就开始解决皇后问题。既然如果皇后问题有解,那么肯定是每行有且只有一个解,那么自然就想到循环所有行,然后遍历这个行的所有列,查看行,列相应位置被占用,是不是可以组成一个解。
还是上代码:
package javaCode; import java.util.Arrays; /** * @ClassName: EightQueen * @Description: 这里用一句话描述这个类的作用 * @author xuejupo [email protected] * @date 2015-11-10 上午11:11:08 */ public class EightQueen { private static int sum = 0; //n皇后题目解法 private static int num = 0; // n皇后问题 private static final int n = 4; // 同栏是否有皇后,true表示有 private boolean[] haveQueenForColumn; // 从右上到左下的斜栏中是否有皇后 private boolean[] fromRightTop; // 从左上到右下的斜栏中是否有皇后 private boolean[] fromLeftTop; // 解集 private int[] queen; // 解答编号 // private int num; public EightQueen() { haveQueenForColumn = new boolean[n + 1]; fromRightTop = new boolean[(2 * n) + 1]; fromLeftTop = new boolean[(2 * n) + 1]; queen = new int[n + 1]; } /** * @Title: backtrack * @Description: 这里用一句话描述这个方法的作用 * @param i * @return void 返回类型 */ public void backtrack(int i) { // System.out.println(i); if (i > n) { // System.out.println(Arrays.toString(queen)); System.out.println("----------------最终结果:"); print(); //有一个解就退出,便于分析问题 System.exit(1); } else { for (int j = 1; j <= n; j++) { if ((!haveQueenForColumn[j]) && (!fromRightTop[i + j]) && (!fromLeftTop[i - j + n])) { // 如果没有皇后 queen[i] = j; System.out.println("----------------第"+ sum++ +"步"); System.out.println("占住第"+i+"行,第"+j+"列的位置,并且把相应的斜行设为占用,结果为:"); print(); // 设定为占用 haveQueenForColumn[j] = fromRightTop[i + j] = fromLeftTop[i - j + n] = true; //第i行已经有数据了,然后开始遍历第i+1行 backtrack(i + 1); haveQueenForColumn[j] = fromRightTop[i + j] = fromLeftTop[i - j + n] = false; queen[i] = 0; System.out.println("----------------第"+ sum++ +"步"); System.out.println("发现第"+i+"行,第"+j+"列的位置走不通,把相应位置去掉,结果:"); print(); } } } } protected void print() { // System.out.println("解法"+ ++num +":-------------"); for (int y = 1; y <= n; y++) { for (int x = 1; x <= n; x++) { if (queen[y] == x) { System.out.print(" Q"); } else { System.out.print(" *"); } } System.out.println(); } } public static void main(String[] args) { EightQueen queen = new EightQueen(); queen.backtrack(1); } }
执行结果:
----------------第0步 占住第1行,第1列的位置,并且把相应的斜行设为占用,结果为: Q * * * * * * * * * * * * * * * ----------------第1步 占住第2行,第3列的位置,并且把相应的斜行设为占用,结果为: Q * * * * * Q * * * * * * * * * ----------------第2步 发现第2行,第3列的位置走不通,把相应位置去掉,结果: Q * * * * * * * * * * * * * * * ----------------第3步 占住第2行,第4列的位置,并且把相应的斜行设为占用,结果为: Q * * * * * * Q * * * * * * * * ----------------第4步 占住第3行,第2列的位置,并且把相应的斜行设为占用,结果为: Q * * * * * * Q * Q * * * * * * ----------------第5步 发现第3行,第2列的位置走不通,把相应位置去掉,结果: Q * * * * * * Q * * * * * * * * ----------------第6步 发现第2行,第4列的位置走不通,把相应位置去掉,结果: Q * * * * * * * * * * * * * * * ----------------第7步 发现第1行,第1列的位置走不通,把相应位置去掉,结果: * * * * * * * * * * * * * * * * ----------------第8步 占住第1行,第2列的位置,并且把相应的斜行设为占用,结果为: * Q * * * * * * * * * * * * * * ----------------第9步 占住第2行,第4列的位置,并且把相应的斜行设为占用,结果为: * Q * * * * * Q * * * * * * * * ----------------第10步 占住第3行,第1列的位置,并且把相应的斜行设为占用,结果为: * Q * * * * * Q Q * * * * * * * ----------------第11步 占住第4行,第3列的位置,并且把相应的斜行设为占用,结果为: * Q * * * * * Q Q * * * * * Q * ----------------最终结果: * Q * * * * * Q Q * * * * * Q *
一步一步分析代码结果:
首先,第0步,肯定是占据第1行第1列,然后在第二行的时候用
(!haveQueenForColumn[j]) && (!fromRightTop[i + j]) && (!fromLeftTop[i - j + n])
判断条件,判断第二行的第j列是否可用,如果可用,那么占住该位置,结果判断出第二行第一列和第二列都不可用(因为和第一行第一列的数据冲突)。
第二步,判断第三行,发现第二行第三列占住之后,第三行放什么都走不通了,返回第二行处理,把第二行第三列位置去掉。
第三步,占住第二行第四列,然后balabalabala。。。 跟前几步判断条件一样,最终得到4行都可以放位置的一个位置组合。
大家可能不明白,以后复习时候也可能会疑惑的地方:
// 如果没有皇后 queen[i] = j;
queen[i] = j; 表示第i行第j列被占用了。
haveQueenForColumn[j] = fromRightTop[i + j] = fromLeftTop[i - j + n] = true; //第i行已经有数据了,然后开始遍历第i+1行 backtrack(i + 1); haveQueenForColumn[j] = fromRightTop[i + j] = fromLeftTop[i - j + n] = false;
backtrack(i + 1);为什么放到这里? 这就是回溯法。如果这个表示,当第i行,第j列处理完以后,他会清掉第i行第j列的占用(haveQueenForColumn[j] = fromRightTop[i + j] = fromLeftTop[i - j + n] = false;),然后继续第i+1行,不管第i行处理结果是什么,所以如果代码里面不加这个System.exit(1); 程序会打印出所有的结果。
八皇后其实和四皇后是一样的,只是n不一样而已。令n=8,并且去掉单步打印语句,执行代码后结果:
解法1:------------- Q * * * * * * * * * * * Q * * * * * * * * * * Q * * * * * Q * * * * Q * * * * * * * * * * * Q * * Q * * * * * * * * * Q * * * * 解法2:------------- Q * * * * * * * * * * * * Q * * * * * * * * * Q * * Q * * * * * * * * * * * Q * * * * Q * * * * * Q * * * * * * * * * * Q * * * 解法3:------------- Q * * * * * * * * * * * * * Q * * * * Q * * * * * * * * * Q * * * * * * * * * Q * Q * * * * * * * * * * Q * * * * * Q * * * * * 解法4:------------- Q * * * * * * * * * * * * * Q * * * * * Q * * * * * * * * * * Q * Q * * * * * * * * * Q * * * * * * * * * Q * * * * Q * * * * * 解法5:------------- * Q * * * * * * * * * Q * * * * * * * * * Q * * * * * * * * * Q * * Q * * * * * Q * * * * * * * * * * * * * Q * * * * * Q * * * 解法6:------------- * Q * * * * * * * * * * Q * * * * * * * * * Q * Q * * * * * * * * * Q * * * * * * * * * * * * Q * * * * * Q * * * * * Q * * * * 解法7:------------- * Q * * * * * * * * * * Q * * * * * * * * * Q * * * * Q * * * * Q * * * * * * * * * * * * * * Q * * * * * Q * * * * Q * * * * * 解法8:------------- * Q * * * * * * * * * * * Q * * Q * * * * * * * * * * * * * Q * * * * Q * * * * * * * * * * * Q * * Q * * * * * * * * * Q * * * 解法9:------------- * Q * * * * * * * * * * * Q * * * * * * * * * Q * * Q * * * * * Q * * * * * * * * * * Q * * * * * * * * * * Q * * * * * Q * * * 解法10:------------- * Q * * * * * * * * * * * * Q * * * Q * * * * * * * * * * Q * * * * * * * * * Q * * * * Q * * * Q * * * * * * * * * * Q * * * * 解法11:------------- * Q * * * * * * * * * * * * Q * * * * * Q * * * * * * * * * * Q Q * * * * * * * * * * Q * * * * * * * * * Q * * * * Q * * * * * 解法12:------------- * Q * * * * * * * * * * * * * Q * * * * * Q * * Q * * * * * * * * * Q * * * * * * * * * Q * * * * * * * * * Q * * * * Q * * * * 解法13:------------- * * Q * * * * * Q * * * * * * * * * * * * * Q * * * * * Q * * * * * * * * * * Q * Q * * * * * * * * * Q * * * * * * * * * Q * * 解法14:------------- * * Q * * * * * * * * * Q * * * * Q * * * * * * * * * * * * * Q Q * * * * * * * * * * * * * Q * * * * Q * * * * * * * * * Q * * 解法15:------------- * * Q * * * * * * * * * Q * * * * Q * * * * * * * * * * * * * Q * * * * * Q * * * * * Q * * * * * * * * * * Q * Q * * * * * * * 解法16:------------- * * Q * * * * * * * * * Q * * * * * * * * * Q * Q * * * * * * * * * * Q * * * * * Q * * * * * * * * * * * * * Q * * * * * Q * * 解法17:------------- * * Q * * * * * * * * * Q * * * * * * * * * * Q * * * Q * * * * Q * * * * * * * * * * * * * Q * * Q * * * * * * * * * * * Q * * 解法18:------------- * * Q * * * * * * * * * * Q * * * Q * * * * * * * * * * Q * * * * * * * * * * Q Q * * * * * * * * * * * * * Q * * * * Q * * * * 解法19:------------- * * Q * * * * * * * * * * Q * * * Q * * * * * * * * * * * * Q * Q * * * * * * * * * * Q * * * * * * * * * * * Q * * * * Q * * * 解法20:------------- * * Q * * * * * * * * * * Q * * * Q * * * * * * * * * * * * Q * * * * * Q * * * Q * * * * * * * * * * * * * * Q * * * Q * * * * 解法21:------------- * * Q * * * * * * * * * * Q * * * * * Q * * * * Q * * * * * * * * * * * * * * Q * * * * Q * * * * * * * * * Q * * Q * * * * * * 解法22:------------- * * Q * * * * * * * * * * Q * * * * * Q * * * * * Q * * * * * * * * * * * * * Q * * * * Q * * * * * * * * * Q * Q * * * * * * * 解法23:------------- * * Q * * * * * * * * * * Q * * * * * * * * * Q Q * * * * * * * * * * Q * * * * * * * * * * Q * * * * * Q * * * * Q * * * * * * 解法24:------------- * * Q * * * * * * * * * * Q * * * * * * * * * Q Q * * * * * * * * * * * Q * * * * * * * * * Q * * Q * * * * * * * * * Q * * * * 解法25:------------- * * Q * * * * * * * * * * Q * * * * * * * * * Q * Q * * * * * * * * * Q * * * * Q * * * * * * * * * * * * * Q * * * * * Q * * * 解法26:------------- * * Q * * * * * * * * * * * Q * * Q * * * * * * * * * * * * * Q * * * * Q * * * Q * * * * * * * * * * Q * * * * * * * * * Q * * 解法27:------------- * * Q * * * * * * * * * * * Q * * Q * * * * * * * * * * * * * Q * * * * * Q * * * * * Q * * * * Q * * * * * * * * * * * Q * * * 解法28:------------- * * Q * * * * * * * * * * * * Q * * * Q * * * * * * * * * * Q * Q * * * * * * * * * * * * Q * * * Q * * * * * * * * * * Q * * * 解法29:------------- * * * Q * * * * Q * * * * * * * * * * * Q * * * * * * * * * * Q * Q * * * * * * * * * * * * Q * * * Q * * * * * * * * * * Q * * 解法30:------------- * * * Q * * * * Q * * * * * * * * * * * Q * * * * * * * * * * Q * * * * * Q * * * * Q * * * * * * * * * * * Q * * Q * * * * * * 解法31:------------- * * * Q * * * * * Q * * * * * * * * * * Q * * * * * * * * * * Q * * * * * Q * * Q * * * * * * * * * Q * * * * * * * * * * * Q * 解法32:------------- * * * Q * * * * * Q * * * * * * * * * * * * Q * * * Q * * * * * * * * * * Q * * * * * * * * * Q Q * * * * * * * * * * * Q * * * 解法33:------------- * * * Q * * * * * Q * * * * * * * * * * * * Q * * * Q * * * * * * * * * * Q * * * * * * * * * Q * * * * Q * * * Q * * * * * * * 解法34:------------- * * * Q * * * * * Q * * * * * * * * * * * * Q * * * * * Q * * * Q * * * * * * * * * * * * * * Q * * * * * Q * * * * Q * * * * * 解法35:------------- * * * Q * * * * * Q * * * * * * * * * * * * * Q * * * * Q * * * * * * * * * Q * Q * * * * * * * * * Q * * * * * * * * * * Q * * 解法36:------------- * * * Q * * * * * Q * * * * * * * * * * * * * Q * * * * * Q * * Q * * * * * * * * * Q * * * * * * * * * Q * * * * * * * * * Q * 解法37:------------- * * * Q * * * * * * * * * Q * * Q * * * * * * * * * * * Q * * * * Q * * * * * * * * * * * * * Q * * Q * * * * * * * * * * * Q * 解法38:------------- * * * Q * * * * * * * * * Q * * * * * * * * * Q * Q * * * * * * * * * * * * Q * Q * * * * * * * * * Q * * * * * * * * * Q * * * 解法39:------------- * * * Q * * * * * * * * * Q * * * * * * * * * Q * * Q * * * * * Q * * * * * * * * * * * * * Q * * * * * Q * * * * Q * * * * * * 解法40:------------- * * * Q * * * * * * * * * * Q * Q * * * * * * * * * * * * * * Q * * * * Q * * * * Q * * * * * * * * * * * Q * * * * Q * * * * * 解法41:------------- * * * Q * * * * * * * * * * Q * * * Q * * * * * * * * * * * * Q * Q * * * * * * * * * * Q * * * Q * * * * * * * * * * * * Q * * 解法42:------------- * * * Q * * * * * * * * * * Q * * * * * Q * * * * Q * * * * * * * * * * * Q * * Q * * * * * * * * * Q * * * * * * * * * * * * Q 解法43:------------- * * * Q * * * * * * * * * * Q * * * * * Q * * * * * Q * * * * * Q * * * * * * * * * * * * Q * * * * * * * * * Q * Q * * * * * * 解法44:------------- * * * Q * * * * * * * * * * * Q Q * * * * * * * * * Q * * * * * * * * * * Q * * * Q * * * * * * * * * * * * Q * * * * * Q * * * 解法45:------------- * * * Q * * * * * * * * * * * Q Q * * * * * * * * * * * Q * * * * * * * * * Q * * Q * * * * * * * * * * * Q * * * * Q * * * * * 解法46:------------- * * * Q * * * * * * * * * * * Q * * * * Q * * * * * Q * * * * * Q * * * * * * * * * * * * * Q * * Q * * * * * * * * * * * Q * * 解法47:------------- * * * * Q * * * Q * * * * * * * * * * Q * * * * * * * * * Q * * * * * * * * * Q * Q * * * * * * * * * * * * Q * * * Q * * * * * 解法48:------------- * * * * Q * * * Q * * * * * * * * * * * * * * Q * * * Q * * * * * Q * * * * * * * * * * * * Q * * * Q * * * * * * * * * * Q * * 解法49:------------- * * * * Q * * * Q * * * * * * * * * * * * * * Q * * * * * Q * * * * Q * * * * * * * * * * * Q * * Q * * * * * * * * * Q * * * * 解法50:------------- * * * * Q * * * * Q * * * * * * * * * Q * * * * * * * * * Q * * * * * * * * * Q * * Q * * * * * Q * * * * * * * * * * * * * Q * 解法51:------------- * * * * Q * * * * Q * * * * * * * * * Q * * * * * * * * * * Q * * * Q * * * * * * * * * * * * Q * * * * * Q * * Q * * * * * * * 解法52:------------- * * * * Q * * * * Q * * * * * * * * * * * Q * * Q * * * * * * * * * * * * * Q * * * * Q * * * * * * * * * * * Q * * Q * * * * * 解法53:------------- * * * * Q * * * * Q * * * * * * * * * * * * * Q Q * * * * * * * * * * Q * * * * * * * * * * Q * * * Q * * * * * * * * * * Q * * 解法54:------------- * * * * Q * * * * * Q * * * * * Q * * * * * * * * * * * * Q * * * * * * * * * Q * Q * * * * * * * * * Q * * * * * * * * * * Q * 解法55:------------- * * * * Q * * * * * Q * * * * * Q * * * * * * * * * * * * * Q * * Q * * * * * * * * * * * * * Q * * * * * Q * * * * * Q * * * * 解法56:------------- * * * * Q * * * * * Q * * * * * * * * * * * * Q * * * Q * * * * * * * * * * Q * Q * * * * * * * * * * * * Q * * * Q * * * * * * 解法57:------------- * * * * Q * * * * * * * * * Q * Q * * * * * * * * * Q * * * * * * * * * * * * Q * * * * * Q * * * * * Q * * * * * Q * * * * * * 解法58:------------- * * * * Q * * * * * * * * * Q * Q * * * * * * * * * * Q * * * * * Q * * * * * * * * * * * * * Q * * * * * Q * * * * Q * * * * * 解法59:------------- * * * * Q * * * * * * * * * Q * * Q * * * * * * * * * Q * * * * * * * * * * * Q Q * * * * * * * * * Q * * * * * * * * * * Q * * 解法60:------------- * * * * Q * * * * * * * * * Q * * Q * * * * * * * * * * * Q * * * * Q * * * * * Q * * * * * * * * * * Q * * * * * * * * * * * Q 解法61:------------- * * * * Q * * * * * * * * * Q * * Q * * * * * * * * * * * Q * * * * Q * * * * * Q * * * * * * * * * * * * * * Q * * * Q * * * * 解法62:------------- * * * * Q * * * * * * * * * Q * * * * Q * * * * Q * * * * * * * * * Q * * * * * * * * * * * * Q * * * * * Q * * * Q * * * * * * 解法63:------------- * * * * Q * * * * * * * * * * Q * * * Q * * * * Q * * * * * * * * * Q * * * * * * * * * * Q * * * Q * * * * * * * * * * * * Q * 解法64:------------- * * * * Q * * * * * * * * * * Q * * * Q * * * * Q * * * * * * * * * * * * * Q * * Q * * * * * * * * * * * Q * * * * Q * * * * * 解法65:------------- * * * * * Q * * Q * * * * * * * * * * * Q * * * * Q * * * * * * * * * * * * * Q * * Q * * * * * * * * * * * Q * * * * Q * * * * 解法66:------------- * * * * * Q * * * Q * * * * * * * * * * * * Q * Q * * * * * * * * * Q * * * * * * * * * Q * * * * * * * * * * Q * * * Q * * * * 解法67:------------- * * * * * Q * * * Q * * * * * * * * * * * * Q * Q * * * * * * * * * * Q * * * * * * * * * * * Q * * * * Q * * * * * Q * * * * * 解法68:------------- * * * * * Q * * * * Q * * * * * Q * * * * * * * * * * * * * Q * * * * * Q * * * * * * * * * * Q * Q * * * * * * * * * Q * * * * 解法69:------------- * * * * * Q * * * * Q * * * * * Q * * * * * * * * * * * * * * Q * * * Q * * * * * Q * * * * * * * * * * * * Q * * * * * Q * * * 解法70:------------- * * * * * Q * * * * Q * * * * * Q * * * * * * * * * * * * * * Q * * * * Q * * * * Q * * * * * * * * * Q * * * * * * * * * * Q * 解法71:------------- * * * * * Q * * * * Q * * * * * * * * * Q * * * * * * * * * Q * Q * * * * * * * * * * Q * * * * * Q * * * * * * * * * * * * * Q 解法72:------------- * * * * * Q * * * * Q * * * * * * * * * Q * * * * * * * * * * Q Q * * * * * * * * * * Q * * * * * Q * * * * * * * * * * * * Q * 解法73:------------- * * * * * Q * * * * Q * * * * * * * * * * * Q * * Q * * * * * * * * * Q * * * * * * * * * * * Q Q * * * * * * * * * * * Q * * * 解法74:------------- * * * * * Q * * * * Q * * * * * * * * * * * Q * * Q * * * * * * * * * * * * * Q * * * * Q * * * Q * * * * * * * * * * Q * * * * 解法75:------------- * * * * * Q * * * * Q * * * * * * * * * * * Q * * * * Q * * * * Q * * * * * * * * * * * * * * Q * Q * * * * * * * * * * Q * * * 解法76:------------- * * * * * Q * * * * * Q * * * * Q * * * * * * * * * * * Q * * * * * * * * * * Q * Q * * * * * * * * * * * * Q * * * Q * * * * * 解法77:------------- * * * * * Q * * * * * Q * * * * * Q * * * * * * * * * * * * * Q * * * * Q * * * * * * * * * Q * Q * * * * * * * * * Q * * * * * 解法78:------------- * * * * * Q * * * * * Q * * * * * * * * * * Q * Q * * * * * * * * * Q * * * * * * * * * Q * * * * Q * * * * * * * * * * * * * Q 解法79:------------- * * * * * Q * * * * * Q * * * * * * * * * * Q * Q * * * * * * * * * * * * * * Q * Q * * * * * * * * * * Q * * * * * Q * * * * * 解法80:------------- * * * * * Q * * * * * * * * * Q * Q * * * * * * * * * Q * * * * Q * * * * * * * * * * * * * Q * * * * * Q * * * * * Q * * * * * 解法81:------------- * * * * * * Q * Q * * * * * * * * * Q * * * * * * * * * * * * Q * * * * * Q * * * * * Q * * * * * Q * * * * * * * * * * Q * * * 解法82:------------- * * * * * * Q * * Q * * * * * * * * * Q * * * * Q * * * * * * * * * * * * * * Q * * * * Q * * * * * Q * * * * * * * * * * Q * * 解法83:------------- * * * * * * Q * * Q * * * * * * * * * * * Q * * * * Q * * * * * Q * * * * * * * * * * Q * * * * * * * * * * * Q * * * * Q * * * 解法84:------------- * * * * * * Q * * * Q * * * * * Q * * * * * * * * * * * * Q * * * * * * * * * Q * * * * Q * * * * Q * * * * * * * * * Q * * * * 解法85:------------- * * * * * * Q * * * Q * * * * * * * * * * * * Q * Q * * * * * * * * * * Q * * * Q * * * * * * * * * * * * Q * * * * * Q * * * * 解法86:------------- * * * * * * Q * * * * Q * * * * * Q * * * * * * * * * * Q * * * * * * * * * * Q Q * * * * * * * * * Q * * * * * * * * * * Q * * 解法87:------------- * * * * * * Q * * * * Q * * * * * Q * * * * * * * * * * * * * Q * * * * * Q * * Q * * * * * * * * * Q * * * * * * * * * Q * * * 解法88:------------- * * * * * * Q * * * * * Q * * * * * Q * * * * * Q * * * * * * * * * * * * Q * * * * * * * * * Q * Q * * * * * * * * * Q * * * * 解法89:------------- * * * * * * * Q * Q * * * * * * * * * Q * * * * Q * * * * * * * * * * * * * Q * * * * * Q * * * * * Q * * * * * * * * * * Q * * 解法90:------------- * * * * * * * Q * Q * * * * * * * * * * Q * * * * * Q * * * * * Q * * * * * * * * * * * * * Q * * * * Q * * * * * * * * * Q * * 解法91:------------- * * * * * * * Q * * Q * * * * * Q * * * * * * * * * * * * Q * * * Q * * * * * * * * * * Q * * * * * * * * * Q * * * * Q * * * * 解法92:------------- * * * * * * * Q * * * Q * * * * Q * * * * * * * * * Q * * * * * * * * * * Q * * * Q * * * * * * * * * * * * Q * * * * * Q * * *