N皇后问题

题目

在这里插入图片描述
输入:n = 4
输出:[[“.Q…”,“…Q”,“Q…”,“…Q.”],[“…Q.”,“Q…”,“…Q”,“.Q…”]]
解释:如上图所示,4 皇后问题存在两个不同的解法。

分析

问:用什么方法?
答:递归

问:如何判断格子在同一对角线?
答:同一正对角线的行数-列数相等,同一负对角线的行数+列数相等

问:如何用一维数组记录皇后位置?
答:下标记录行号,值记录列号。

题解

package com.company.test5;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test5 {
    static int n=4;
    static List<List<String>> list=new ArrayList<>();
    public static void main(String[] args) {

        int[] record=new int[n+1];
//        record[1]=2;

//        System.out.println(check(record, 2, 1));
        board(record,1);
//        for (String[] arr : list) {
//            System.out.println(Arrays.toString(arr));
//        }

        System.out.println(list);
        return;


    }
    public static void board(int[] record,int r){

        if(r==n+1){
//            System.out.println(Arrays.toString(record));
//            将record[2,4,1,3]构造成[".Q..","...Q","Q...","..Q."]这种形式
//            ①将2构造成".Q.."
            List<String> arr=new ArrayList<>();
            for (int i = 0; i < n; i++) {
                String s=replace(record[i+1]);
                arr.add(s);
            }

//            存入list
            list.add(arr);
            return;
        }
        for (int i = 1; i <n+1 ; i++) {
//            检查r行,i列可不可以放棋子?
//            i列的前r-1行是否有其它棋子也在c列?(record[1,2,3,4]!=c)
//            该格子的对角线是否有其它棋子?
// (r,c)(i,record[i])在同一正对角线,r-c=i-record[i]
// (r,c)(m,n)在同一负对角线,r+c=m+n

            if(check(record,r,i)){
                record[r]=i;
                board(record,r+1);
            }

        }
    }

    private static String replace(int m) {
//        n=2
//        String s=".Q..";
//        Q前面有n-1个点,Q后面有4-n个点

        StringBuilder b=new StringBuilder();
        for (int i = 0; i < m - 1; i++) {
            b.append(".");
        }
        b.append("Q");
        for (int i = 0; i < n - m; i++) {
            b.append(".");
        }
        return b.toString();
    }

    private static boolean check(int[] record, int r, int c) {

        for (int i = 1; i < r; i++) {
            if(record[i]==c){
                return false;
            }
            if(i-record[i]==r-c){
                return false;
            }
            if(i+record[i]==r+c){
                return false;
            }
        }
        return true;



    }
//
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值