蓝桥杯【2n皇后问题】Java

问题描述

     给定一个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

解题思路

  n x n 的棋盘摆放n个黑皇后和n个白皇后,且同肤色皇后不能同行同列同对角线,则每行必定为一黑一白。可令2代表黑皇后,3代表白皇后,我们先将黑皇后安顿好再安顿白皇后。首先挨行检索有无皇后容身之处,前提要满足该位置为1,其次判断前几行放置的黑皇后是否与当前位置不同列且不同对角线,若以上条件都满足则将皇后放到当前位置(将当前位置设置为2),若不满足则检索该行下一位置,倘若整行都没有合适位置,则回溯至上一行移动黑皇后的位置,重复以上步骤,对于白皇后的操作亦是如此。另外,在一种方案检索完毕后,要记得还原棋盘,以便下一方案可行性的测试。

代码实现

import java.util.Scanner;

public class Main {
    
    
	static int n, sum = 0;// n:棋盘边长(皇后数量),sum:不同摆法
	static int[][] chess;// 棋盘

	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		chess = new int[n][n];
		for (int i = 0; i < n; i++) {
    
    
			for (int j = 0; j < n; j++) {
    
    
				chess[i][j] = sc.nextInt();// 初始化棋盘
			}
		}
		dfs(0, 2);// 从第一行开始检索摆放皇后的位置 0为第一行的下标,用2代表黑皇后,3代表白皇后
		System.out.println(sum);
	}

	static void dfs(int line, int queen) {
    
    
		if (line == n) {
    
    // 若n行都已放置皇后
			if (queen == 2)// 若之前放置的为黑皇后
				dfs(0, 3);// 从第一行开始检索白皇后的摆放位置
			else// 若放置的为白皇后(则黑白皇后都已放置完毕)
				sum++;// 摆放方案+1
		} else {
    
    // 尚未放置到最后一行
			for (int j = 0; j < n; j++) {
    
    
				if (chess[line][j] == 1 && check(line, j, queen)) {
    
    // 判断该点是否满足皇后放置条件
					chess[line][j] = queen;// 放置皇后
					dfs(line + 1, queen);// 进行下一行的检索
					chess[line][j] = 1;// 还原棋盘
				}
			}
		}
	}

	static boolean check(int line, int row, int queen) {
    
    
		for (int i = line - 1; i >= 0; i--) {
    
    // 判断当前位置所在列是否有该皇后
			if (chess[i][row] == queen)
				return false;
		}
		for (int i = line - 1, j = row - 1; i >= 0 && j >= 0; i--, j--) {
    
    // 判断反斜线上是否存在该皇后
			if (chess[i][j] == queen)
				return false;
		}
		for (int i = line - 1, j = row + 1; i >= 0 && j < n; i--, j++) {
    
    // 判断斜线上是否存在该皇后
			if (chess[i][j] == queen)
				return false;
		}
		return true;
	}
}

运行截图

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_50816725/article/details/112702058