递归方法求八皇后问题

**

递归方法求八皇后问题

**

  • column[]代表列不相同; lead[]代表主对角线不相同; minor[]代表次对角线不相同
  • 宏定义Q为皇后数及Q阶棋盘
  • 如果两个皇后Q1(x1, y1)和Q2(x2, y2)不符合要求,则以下四个条件之一必符合(这里我的想法是x为列,y为行)
    1. x1 == x2(表示两个皇后刚好在同一列)
    2. y1 == y2(表示两个皇后刚好在同一行)
    3. x1 + y1 == x2 +y2(次对角线)
    4. x1 - y1 == x2 - y2(主对角线)
  • 因为递归方法参数为行,则同一行的可能性不用考虑,只需要考虑列、主对角线和次对角线即可
  • 对角线定义的数组容量Q*2+1的理由:次对角线Max为Q+Q,且数组从1开始
public class test_1 {
 final int Q = 8;  //定义n*n个皇后
 //数组中之所以+1,我们的行列从1开始算
 int[] column = new int[Q+1];  //列
 int[] lead = new int[Q*2+1];  //主对角线
 int[] minor = new int[Q*2+1];  //次对角线
 int[] queen = new int[Q+1];   //用于打印图形
 public int num = 0;



  //构造方法,初始化棋盘,清空皇后
 public test_1(){
  for(int i=1; i <= Q ;i++)
   column[i] = 0;
  for(int i=1; i <= Q*2; i++){
   lead[i] = 0;
   minor[i] = 0;
  }
 }



  //递归
 void backtrack(int i){
  //当i>Q时,结束
  if(i>Q){
   showAnswer();
  }else{
   for(int j = 1; j <= Q; j++){
    if(column[j] == 0 && lead[i-j+Q] == 0 && minor[i+j] == 0){  //对应相应的i行,j列等等(i行是重点!!)
     queen[i] = j;  //皇后落点
     column[j] = lead[i-j+Q] = minor[i+j] = 1;  //相应的列、主对角线、次对角线无法再次占位
     backtrack(i+1);         //递归i+1行
     column[j] = lead[i-j+Q] = minor[i+j] = 0;  //没有真实皇后的位置返回0,此时递归到了最后一次
    }
   }
  }
 }



  //打印所有可能性
 void showAnswer(){
  num++;
  System.out.println("第" + num + "种可能性");
  for(int i = 1; i <= Q; i++){
   for(int j = 1; j <= Q; j++){
    //一个个判断,前面已经为queen[i]赋值
    if(queen[i] == j){
     System.out.print("Q");
    }else{
     System.out.print("×");
    }
   }
   System.out.println();
  }
 }
  
 
    public static void main(String[] args) {
        test_1 queen = new test_1();
        queen.backtrack(1);
    }
}

花了好长时间理解的八皇后问题,期间还手动推算过,记录一下!

你可能感兴趣的:(Java编程)