蓝桥杯:基础练习 2n皇后问题

基础练习 2n皇后问题:


资源限制:

时间限制:1.0s
内存限制:512.0MB


问题描述:

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


## 代码实现:

import java.util.Scanner;

public class Main {
	static int[][] cc;//保存题中输入的二维数组
	static int count = 0 , n;//count为最终答案 ,n为阶数
	static int[] num1 , num2;//分别代表放置白皇后,黑皇后的数组
	//下标代表行号,num1[1]=5,表示当前白皇后放置在第2行第6列
	//num2同理
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		n = in.nextInt();
		cc = new int[n][n];
		num1 = new int[n];
		num2 = new int[n];
		for(int i=0;i<cc.length;i++) {
			for(int j=0;j<cc[0].length;j++) {
				cc[i][j] = in.nextInt();
			}
		}
		run1(0);
		System.out.println(count);
	}
	//x表示当前要放置x个皇后(从0开始算0,1,2,3,...,n-1)
	public static void run1(int x) {
		//如果对应白皇后放置到第n个,也就是放置等于第x个(x=数组长度)时,意味着白皇后当前已经找到一种放置的解,这个时候开始放置黑皇后,run2(0)
		//当黑皇后放置完后退到这里return会白皇后的上一层,找下一种解法,依次这样...
		if(x>=cc.length) {
			run2(0);
			return;
		}
		for(int i=0;i<n;i++) {
			if(cc[x][i]==0) {
				continue;
			}
			num1[x] = i;
			if(check(x , num1)) {
				run1(x+1);
			}
		}
	}
	
	public static void run2(int x1) {
		if(x1>=cc.length) {
			count++;
			return;
		}
		for(int i=0;i<n;i++) {
			if(cc[x1][i]==0 || num1[x1]==i) {
				continue;
			}
			num2[x1] = i;
			if(check(x1, num2)) {
				run2(x1+1);
			}
		}
	}
	//num[i]==num[n] 表示放置在了同一列
	//Math.abs(i-n)==Math.abs(num[i]-num[n]) 表示放置同一斜线上(45°)
	public static boolean check(int n ,int[] num) {
		for(int i=0;i<n;i++) {
			if(num[i]==num[n] || Math.abs(i-n)==Math.abs(num[i]-num[n]) ) {
				return false;
			}
		}
		return true;
	}
}

今天的学习到这里结束了。
这是之前写的,今天算是总计一下。
鄙人水平有限,若有写的不妥当打地方 还请大佬指正。
又看不懂的地方,留言给我。
最后最后。如果你看了有所收获,可不可以点赞(你觉得还可),评论(还不错给点支持),转发(谢谢谢~~)
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不坦然

承蒙厚爱~

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

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

打赏作者

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

抵扣说明:

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

余额充值