判断N皇后是否能够相互攻击

N皇后是常见的算法题,那我们如何去判断当前N皇后是否存在相互攻击情况呢?

判断N皇后不能相互攻击需要满足一下三种条件:

  • 任意两个皇后不能在同一行
  • 任意两个皇后不能在同一列
  • 任意两个皇后不能在同一条对角线[主副对角线]上

判断步骤

  1. 借助辅助数组locations[N][N]来记录皇后的位置,每初始化一行(根据每一行输入的皇后位置)就记录一次
  2. 记录的时候我们就借助上述条件来进行初始化,将当前皇后所在位置的行、列、主副对角线都记录(假设都置为1)
  3. 每一行输入的皇后位置都会与辅助数组locations判断。
    如果当前输入行存在2个及其以上的皇后,那么就直接置为true(表示会进行相互攻击);
    如果当前皇后的位置在辅助数组locations中,即realLocations[i][j]==locations[i][j],说明当前位置不能放置皇后了,直接置为true(表示会进行相互攻击)

因此,根据以上步骤可以写出以下代码

import java.util.Scanner;

public class NQueen {
    public static boolean res = false;//不能相互攻击
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        int[][] locations = new int[N][N];
        int[][] realLocations = new int[N][N];
        locations[0][1] = 1;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                realLocations[i][j] = scanner.nextInt();
            }
        }
        for (int i = 0; i <N; i++) {
            initLocations(realLocations,locations,i);
        }
        System.out.println(res);
    }
    public static void initLocations(int[][] realLocations,int[][] locations,int i){
        int count = 0,col = 0;
        for (int j = 0; j < locations.length; j++) {
            if (realLocations[i][j]==1){
                count++;
                col = j;//记录该行皇后出现的位置
            }

        }
        if (count>1||locations[i][col]==1){//如果该行出现的皇后次数大于1或者当前位置已经放置皇后 则可以相互攻击
            res = true;
            return;
        }

        for (int j = 0; j <locations.length ; j++) {
            locations[i][j] = 1;//该行置为1 表示之后无法在该行放置皇后
            locations[j][col] = 1;//该列设置为1 表示之后无法在该列放置皇后
        }
        for (int j = 0; j < col; j++) {
            locations[j][col-j]=1;//副对角线置为1 表示之后无法在该副对角线上放置皇后
        }
        for (int k=col;k<locations.length;k++){
            if (i<locations.length)
                locations[i][k]=1;//主对角线置为1 表示之后无法在该主对角线上放置皇后
            i++;
        }
    }
}

用例测试

8
0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 0 0 0 0 1 0
1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 1 0 0 0
true // 会相互攻击 最后一行和倒数第二行存在副对角线上攻击情况
8
0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0
0 0 0 0 0 0 1 0
1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 1 0 0 0
false // 不会相互攻击
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值