蓝桥杯——受伤的皇后(递归+回溯)

题目描述:

题目描述

有一个 n×n的国际象棋棋盘(n 行 n列的方格图),请在棋盘中摆放 n 个受伤的国际象棋皇后,要求:

  1. 任何两个皇后不在同一行。
  2. 任何两个皇后不在同一列。
  3. 如果两个皇后在同一条 45 度角的斜线上,这两个皇后之间行号的差值至少为 3 。

请问一共有多少种摆放方案。

输入描述

输入的第一行包含一个整数 n。

其中,1≤n≤10。

输出描述

输出一个整数,表示答案。

思路

1.不符合的情况下:当第一次调用时,出现这种情况,从而导致无法继续进行递归,直接返回为void。

2.符合的情况下,让count++,并对最后一行进行回溯,让它的前一列继续向前移动,进行递归。

(图片为不符合情况下)

image-20230303154412788

import java.util.Scanner;

/**
 * 任何两个皇后不在同一行。
 任何两个皇后不在同一列。
 如果两个皇后在同一条 45 度角的斜线上,这两个皇后之间行号的差值至少为 3 。96%
 *
 */
public class Time {
    // n皇后变种
    public static void main(String[] args) {
        Scanner scanner =new Scanner(System.in);
        int n=scanner.nextInt();

        //创建一个棋盘
        int[][] arr=new int[n][n];
        int row = 0;
        dfs(arr,row);
        System.out.println(count);
    }
    static int count=0;
    private static void dfs(int[][] arr,int row) {
        //递归跳出条件1
        if (row== arr.length){
          count++;
          return;
        }

        for (int col = 0; col< arr.length; col++) {
            if (contins(arr,row,col)) {
                arr[row][col]=1;
                dfs(arr, row+1);  //递归调用
                arr[row][col]=0;  //回溯
            }
        }
    }//当递归一次结束后没有满足上面的递归跳出条件,说明没有完成排序需要进行回溯

    //符合题意返回true,否则返回false
    private static boolean contins(int[][] arr,int row, int col) {
        //判断同一列是否有1

        int col1=col;
        for (int j = 0; j < row;  j++) {
            if(arr[j][col1]==1) {
                return false;
            }
        }

        int row2=row;
        int col2=col;
        //判断左上45度
        for (int i = 0; i<3; i++) { //判断左上三格

            if (row2==0||col2==0) {//当行或列的值为零的时候
                if (arr[row2][col2]==1){ //并且当前值等于1,就返回false
                    return false;
                }else {
                    break;
                }
            }

            if(arr[row2--][col2--]==1) {
                return false;
            }
        }


        int row3=row;
        int col3=col;
        //判断右上45度
        for (int i = 0; i<3; i++) {//判断右上三格
            if (row3==0||col3== arr.length-1){//当前行的值等于0,或者当前列的值等于数组长度的时候
                if (arr[row3][col3]==1){//并且当前值等于1的情况下,也返回false
                    return false;
                }else {
                    break;
                }
            }

            if(arr[row3--][col3++]==1) {
                return false;
            }
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fang GL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值