ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

2021年了还不懂回溯算法吗(八皇后递归问题)

2021-02-23 16:58:26  阅读:11  来源: 互联网

标签:arr 递归 int max ++ 2021 回溯 皇后 public


一、 八皇后问题?

在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法?

二、思路

1.首先如何解决递归问题呢?

 *找到递推公式
 *找到递归出口

2.那么递推公式是什么呢?
毫无疑问,第一个皇后在二维数组的第一行,第二个皇后在二维数组的第二行·········,那么递推公式就肯定是n+1 了;

3.递归出口是什么呢?

一共8个皇后,那出口肯定就是下到第八个皇后呗

4.考虑的细节都有哪些

1.如果要计算出所有的情况,那么肯定要使用回溯算法;如果我现在皇后所下的位置是第八行的第i列,如果此时发现该位置不满足情况,那我的i就要移动到i+1的位置,查看该位置是否符合情况;所以需要使用一个for循环对每一行进行遍历,当该皇后在该位置不满足情况时就向后移动一位;

2.如果我已经下到了第八个皇后,在该行遍历结束之后,会返回到上一个皇后的调用处,然后将上一个皇后的位置进行i+1;这就是回溯的体现

3.优化,可以使用一个全局共享的一维数组用来代替二维数组,下标代表第几行,数组数据代表皇后在每一行的第几个位置

4.需要一个判断函数,横竖斜线是否相遇

三、代码

package com.company;

/**
 * @author:抱着鱼睡觉的喵喵
 * @date:2021/2/22
 * @description:
 */
public class QueenEight {

    private int max = 8;
    private int[] arr = new int[max];
    private static int count = 0;

    public static void main(String[] args) {

        QueenEight queenEight = new QueenEight();
        queenEight.check(0);
        System.out.printf("一共有%d解法",count);
    }
    public void check(int n) {
        if (n == max) {
            print();
            return;
        }
        for (int i = 0; i < max; i++) {
            arr[n] = i;
            if (judge(n)) {
                check(n + 1);
            }
        }

    }
    public boolean judge(int n) {
        for (int i = 0; i < n; i++) {
            if (arr[n] == arr[i] || Math.abs(n - i) == Math.abs(arr[n] - arr[i])) {
                return false;
            }
        }
        return true;
    }

    public void print() {
        count++;
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] +" ");
        }
        System.out.println();
    }
}

标签:arr,递归,int,max,++,2021,回溯,皇后,public
来源: https://blog.csdn.net/Kevinnsm/article/details/113995783

专注分享技术,共同学习,共同进步。侵权联系[admin#icode9.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有