八皇后java解法(韩顺平老师b站视频自学)

本文详细描述了使用递归和回溯算法解决八皇后问题的过程,包括皇后放置的规则、判断冲突的方法以及如何利用逻辑关系控制递归的终止。
摘要由CSDN通过智能技术生成

老师视频思路:

1.第一个皇后先放第一行第一列;
 2.第二个皇后放在第二行第一列、然后判断是否 OK,如果不 OK,则尝试放在第二列、第三列…,直到找到一个合适的位置;
3.继续放置第三个皇后,还是第一列、第二列…,直到找到一个合适的位置;
4.依次循环下去,直到第 8 个皇后也能放在一个不冲突的位置,就算是找到了一个正确解;
5.当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯。本次回溯之后,会即将第一个皇后放到第一列前提下的所有正确解全部得到;
6.然后回头从 1 开始,第一个皇后放到第一行第二列,后面继续循环执行 2、3、4 的步骤,直至第一个皇后将第一行的所有列都放置过。至此,便得到了八皇后问题的所有放置解法。

思路:

n表示第n+1个皇后,i表示第i+1行,arr[i]表示第arr[i]+1列

举例:在[0, 4, 7, 5, 2, 6, 1, 3]中,7为arr[2],表示第3行第8列

判断第n个皇后是否会攻击之前放置的皇后的方法:

①判断是否在同一行

因为每次放置一个皇后之后,i会加1,所以前后的皇后肯定不在同一行

②判断是否在同一列

arr[i]==arr[n];

③判断是否在同一斜线上

观察棋盘发现规律,如果前后的皇后在同一斜边上,那么前后皇后所在行数的差的绝对值会等于所在列数的绝对值

Math.abs(arr[n]-arr[i])==Math.abs(n-i);

代码及注释:


public class EightQueen{
    public static void main(String[] args){
        T t=new T();
        t.put(0);//从第1个皇后开始,一直到第8个皇后结束
        System.out.println(t.count);//看看一种有多少种摆放的方法
    }
}

class T{
    int[] arr=new int[8];//创建数组来存储8个皇后的位置
    int count=0;//表示存在多少种可能

    public void print(){
        for(int i=0;i<arr.length;i++){
            System.out.print(arr[i]+" ");//打印出八皇后的拜访位置
        }
        System.out.println();
        count++;//每摆完一次第8个皇后,该数字就加一,用以统计摆放的方法数
    }

    public boolean judge(int n){//判断放的第n+1个皇后是否合理
        for(int i=0;i<n;i++){
//i<n,意思是判断第n+1个皇后和前面已经摆好的n个皇后是否会相互攻击
            if(arr[n]==arr[i]||Math.abs(arr[n]-arr[i])==Math.abs(n-i)){
//分别判断前后摆放的皇后是否在同一列,是否在同一斜线上
                return false;
            }
        }
        return true;
    }

    public int put(int n){
        if(n==8){
            print();//表示摆完了8个皇后,就输出这种摆放情况的可能性
        }else {//如果还没有摆完8个皇后,就继续摆放
            for(int i=0;i<8;i++){
                arr[n]=i;//第n+1个皇后在改行的每一列都放置并进行检验
                if(judge(n)){
//如果该列的放置是合理的,则进行下一个皇后的放置,否则继续for循环,去检验放在下一列是否合理
                    put(n+1);
                }
            }
        }
        return count;
    }
}

关键在于把握住什么时候跳出递归,搞清楚逻辑关系。

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值