八皇后问题-回溯经典

八皇后问题

题目

要在8*8的国际象棋棋盘中放8个皇后,使任意两个皇后都不能互相吃掉。规则是皇后能吃掉同一行、同一列、同一对角线的棋子。
下图是符合摆放的一种情况
在这里插入图片描述
开始的思路是二维深搜,果然超时不行,没有注意题目特点,明显的回溯递归(相邻两层互不相同,相互影响
理解回溯算法中对每层的操作即可,题意要求相邻两个皇后,不能在同一层,则可等价于在每层递归填一个数即可,递归树的宽度为8。
我们设层数为x,则在该层有皇后对应的列为arr[x],就实现了二维简化为一维(不同行交给递归处理)

判断条件是否符合摆放规则:

  1. 同行:每层递归就保证了不同行
  2. 同列,arr[x]与每层赋的列值j不同
  3. 同对角线:两坐标斜率绝对值为1(y1-y2=x1-x2) 注意用绝对值
for (int k=0;k<i;k++){//对0~i行的数进行判断
        if (arr[k]==j||Math.abs(arr[k]-j)==Math.abs(i-k)){
            flag=false;
        }
    }
    return flag;

代码实现

package 递归与回溯;

import java.util.Map;

//八皇后问题
public class Test01 {
    //棋盘放置,可以用一维简化,下标表行数,值表列数,回溯搜素不同行
    //对应点的坐标即为 (x,arr[x])和(y,arr[y])

    static int []arr;
    private static int ans;

    public static void main(String[] args) {
        arr=new int[8];
        dfs(0);
        System.out.println(ans);
    }

    private static void dfs(int i) {
        if (i==8){
         ans++;
         return;
        }
        for (int j = 0; j < 8; j++) {
            if (isok(i,j)){
                arr[i]=j;//在第i行第j列放置
                dfs(i+1);
                arr[i]=0;
            }

        }
    }

    private static boolean isok(int i,int j) {//第j列
        boolean flag=true;
        for (int k=0;k<i;k++){//0~7列判断
            if (arr[k]==j||Math.abs(arr[k]-j)==Math.abs(i-k)){
                flag=false;
            }
        }
        return flag;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值