@java 蓝 桥 杯 Ejercicios de grupo B ejercicios básicos (30) BÁSICO-027 2n pregunta de reina búsqueda de pregunta de reina ocho

Descripción del problema

Dado un tablero n * n, hay algunas posiciones en el tablero que la reina no puede usar. Ahora tenemos que poner n reinas negras y n reinas blancas en el tablero de ajedrez, de modo que dos reinas negras no estén en la misma fila, la misma columna o la misma diagonal, ni dos reinas blancas en la misma fila, En la misma columna o en la misma diagonal. Pregunte cuántos tipos de métodos de lanzamiento en total? n es menor o igual que 8.
Formato de entrada
  La primera línea de entrada es un número entero n, que indica el tamaño del tablero de ajedrez.
  En las siguientes n filas, hay n enteros de 0 o 1 en cada fila. Si un entero es 1, indica que la posición correspondiente se puede colocar como reina. Si un entero es 0, indica que la posición correspondiente no se puede colocar como reina.
El formato de salida
  genera un número entero, que indica cuántos tipos de métodos de colocación en total.
Entrada de muestra
4
1 1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
Salida
de
muestra 2 Entrada de muestra
4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1
Salida de muestra
0


```java
/*
	   Aurora   2020年4月16日
问题描述
  给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑
       皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共
       有多少种放法?n小于等于8。
输入格式
  输入的第一行为一个整数n,表示棋盘的大小。
  接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的
       位置不可以放皇后。
输出格式
  输出一个整数,表示总共有多少种放法。
样例输入
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
样例输出
2
样例输入
4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1
样例输出
0  
 */
package 基础BASIC;

import java.util.Scanner;

public class 二n皇后问题 {
    static Scanner scanner = new Scanner(System.in);		//定义静态键入方法
    static int n = scanner.nextInt();						//键入数组阶数  n
    static int count=0;										//定义一个静态变量:用来统计可行方法的数量   count
    public static void main(String[] args) {				//定义Main方法
        int[][] a = new int[n][n];							//定义二维数组(长度为n)
        for (int i = 0; i < n; i++) {						//给数组赋值
            for (int j = 0; j < n; j++) {
                a[i][j] = scanner.nextInt();				//录入数组的值
            }
        }
        dfs(a,0);											//调用dfs方法
        System.out.println(count);
    }
    public static void dfs(int[][] a,int N){				//定义dfs(有参实例)方法
        if(N==n){											//如果N等于n(若本次调用dfs方法传入的参数N等于矩阵的阶n则执行以下代码:)
            int flag=0;										//定义一个整型变量 flag
            for (int i=0;i<n;i++){							//遍历数组a,统计等于2的元素个数
                for (int j=0;j<n;j++){
                    if(a[i][j]==2){							//若第i行第j列的元素等于2,则flag加一,
                        flag++;
                    }
                }
                if(flag!=1){								//若flag不等于1,则返回(结束本次调用dfs)
                    return;
                }
                else {										//若flag等于1,则给flag赋值为0
                    flag=0;
                }
            }
            dfs2(a,0);										//循环完之后,调用dfs2方法,
            return;											//返回:结束本方法
        }
        for (int i=0;i<n;i++){
            if(check(a,N,i)){								//调用check方法,若返回true,则执行代码块:
                a[N][i]=2;									//给数组a第N行,第i列位置赋值为2
                dfs(a,N+1);									//调用dfs方法(调用自身:递归思想),并且N+1,即:N从0开始,直到与矩阵的阶相等
                a[N][i]=1;									//给数组第N行第i列赋值为1,其作用为:
            }
        }
    }
    public static void dfs2(int[][] a,int N){				//定义dfs2有参方法,
        if(n==N){											//若传入参数N等于矩阵的阶n,则如下执行代码块:
            int flag=0;										//定义一个整型变量flag
            for (int i=0;i<n;i++){							//遍历数组a,进行判断统计等于3的元素个数
                for (int j=0;j<n;j++){
                    if(a[i][j]==3){							//判断,若数组a第i行第j列的值等于3,则flag加一
                        flag++;
                    }
                }
                if(flag!=1){								//判断flag若等于1则赋值为0,否则结束本次方法dfs2的调用
                    return;
                }
                else {
                    flag=0;
                }
            }
            count++;										//每次调用dfs2方法执行到这一行则count加一,即:记录下一种新的可行方案出现
            return;											//结束本次dfs2方法的调用
        }
        for (int i=0;i<n;i++){								//若调用dfs2方法时传入的参数N不等于矩阵的阶n,则执行如下代码块:
            if(check2(a,N,i)){								//调用check2方法,传入参数:数组a,参数N及参数i;若返回为true,则执行如下代码块:
                a[N][i]=3;									//给数组第N行,第i列的元素赋值为3
                dfs2(a, N+1);								//调用dfs2方法,即自身,并且参数为数组a,N+1
                a[N][i]=1;									//给数组第N行第i列位置元素赋值为1
            }
        }
    }
    public static boolean check(int[][] a,int N,int p){		//定义check(检查)方法1
        if(a[N][p]==0) return false;						//如果数组a第N行第p列位置等于0,则返回false
        for (int j=0;j<N;j++){								//行数在N以内循环进行判断
            for (int i = 0; i < n; i++) {					//列数在n以内循环进行判断
                if(a[j][i]==2){								//若数组a中第j行第j列等于2则执行以下判断
                    if(i==p||Math.abs(N-j)==Math.abs(i-p)){	//判断若N减j的绝对值等于i减p的绝对值,返回false
                        return false;
                    }
                }
            }
        }
        return true;										//以上for循环判断完都没有return的话,就返回true(表示当前位置可以放皇后)
    }
    public static boolean check2(int[][] a,int N,int p){	//定义check2(检查)方法2
        if(a[N][p]==0||a[N][p]==2) return false;			//若数组第N行第p列为0或者等于2,则返回false
        for (int j=0;j<N;j++) {								//遍历数组N以内行,阶乘n以内列,
            for (int i = 0; i < n; i++) {
                    if(a[j][i]==3) {						//判断若元素为3则进一步判断
                        if (i == p || Math.abs(N - j) == Math.abs(i - p)) {
                        	//判断若此时i等于p或者N与j差的绝对值等于i与p的差的绝对值,则返回false
                            return false;
                        }
                    }
            }
        }
        return true;//若遍历完都没有返回false,则返回ture(即:此位置可以放)
    }
}

41 artículos originales publicados · Me gusta1 · Visitas1287

Supongo que te gusta

Origin blog.csdn.net/DAurora/article/details/105562398
Recomendado
Clasificación