八皇后问题
http://blog.csdn.net/zhong317/article/details/4586131
8皇后之间需满足:
1.不在同一行上
2.不在同一列上
3.不在同一斜线上
4.不在同一反斜线上
假设前面1列的棋子放在第3行,那当前列不能放的位置就一定是3行,2行,4行。因为如果放在这三行上就分别跟前一列的棋子同在一行、同在斜线、同在反斜线上,不符合我们的要求。现在我们用cols数组来表示8个列棋子所放的行数,数组下标从0开始,其中数组下标表示列数,数组的元素值表示该列棋子所在行数,当前列为N(N>=0,N<8),即cols[N-1]=3,则有:
cols[N] != cols[N-1](=3,表示不在同一行)
cols[N] != cols[N-1]-1(=3-1=2,表示不在同一斜线上)
cols[N]!=cols[N-1]+1(=3+1,表示不在同一反斜线上)
这里我们注意到,如果N-2列存在的话,那么我们还要考虑当前列N不与N-2列的棋子同行,同斜线,同反斜线。把当前列N的前面的某一列设为m,则m的所有取值为{m>=0,m<N}的集合,故又可在上面式子的基础,归纳为如下:
cols[N] != cols[m](与第m列的棋子不在同一行)
cols[N] != cols[m] -(N-m)(>=0 ,与第m列的棋子不在同一斜线上)
cols[N] != cols[m] + (N-m) (<=8-1,与第m列的棋子不在同一反斜线上)
public class Queen8 { public static int num = 0; //累计方案总数 public static final int MAXQUEEN = 8;//皇后个数,同时也是棋盘行列总数 public static int[] cols = new int[MAXQUEEN]; //定义cols数组,表示8列棋子摆放情况 ,第k列放在第cols[k]行 public void getArrangement(int n){ //n表示 //遍历该列所有不合法的行,并用rows数组记录,不合法即rows[i]=true boolean[] rows = new boolean[MAXQUEEN]; for(int i=0;i<n;i++){ rows[cols[i]]=true; //n不能与i同行 int d = n-i; if(cols[i]-d >= 0)rows[cols[i]-d]=true; //n不能与i在同一斜线上 if(cols[i]+d <= MAXQUEEN-1)rows[cols[i]+d]=true; //n不能与i在同一反斜线上 } for(int i=0;i<MAXQUEEN;i++){ //判断该行是否合法 //不合法则跳过这行,继续下一行 if(rows[i])continue; //设置当前列合法棋子所在行数 cols[n] = i; //当前列不为最后一列时 if(n<MAXQUEEN-1){ getArrangement(n+1); }else{ //累计方案个数 num++; //打印棋盘信息 printChessBoard(); } } } //辅助函数,用于打印 public void printChessBoard(){ System.out.println("第"+num+"种走法"); for(int i=0;i<MAXQUEEN;i++){ for(int j=0;j<MAXQUEEN;j++){ if(i==cols[j]){ System.out.print("0 "); }else System.out.print("+ "); } System.out.println(""); } } public static void main(String args[]){ int[] i = cols; int j = i.length; Queen8 queen = new Queen8(); //打印 queen.getArrangement(0); //统计 System.out.println(""); System.out.println(MAXQUEEN+"皇后问题有"+num+"种摆放方法。"); } }
posted on 2017-08-28 22:00 zhangxiaoyu 阅读(126) 评论(0) 收藏 举报
浙公网安备 33010602011771号