蓝桥杯 2n皇后问题(java)

博客围绕蓝桥杯2n皇后问题展开,该问题要求在n*n棋盘放n个黑皇后和n个白皇后,有位置限制。采用DFS算法,先输入棋盘并存储0位置,用一维数组存棋子位置。先放一种皇后再放另一种,递归总层数2n,两种皇后判断摆放条件有差异,最后给出完整代码。

蓝桥杯 2n皇后问题(java)

问题描述
  给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。

解法描述
这题是一道经典的dfs题,但是与八皇后有所不同,因为要放两种皇后,同时给出的棋盘还有不能放的限制,我们要考虑这两种情况。我在输入棋盘时使用了一个列表来储存棋盘中0的位置,之后在判断该位置是否能放皇后时我们会用到这个列表。

		for(int i = 0; i < n; i++) {
			for(int j =0; j < n;j++) {
				if(input.nextInt() == 0) {
					list.add(i+1);
					list.add(j+1);
				}
			}
		}

我还定义了两个一维数组,分别储存两种棋子的位置,数组下标为行数,内容为列数。使用一维数组会比二维数组简单。初始化讲完,接着就是重点dfs函数,我的方法是先放置好一种颜色的皇后,然后再放置另一种颜色的,所以递归的总层数就是2n,也就是结束条件是当row>2n是结束搜索并使总摆法+1。然后就是当row<=n时进行第一个皇后的摆放,搜索完成后摆放第二种皇后。这里要注意两种皇后判断能否摆放的条件不同,第一种皇后只需要先判断该位置是否可放,因为棋盘中存在0位置不能摆放的问题,这时我们就可以使用上面的list列表来进行判断,然后再进行不在同一行、同一列或同一条对角线上的判断。而第二种皇后要加一个对第一种皇后位置的判断,也就是说第一种皇后放过的位置我们就不能再放了。

public static void dfs(int row) {
		if(row > 2 * n) {
			
			count++;
			return;
		}
		
		if(row <= n) {
			for(int i = 1; i <= n; i++) {
				col1[row] = i;
				if(judge1(row, i)) {
					dfs(row+1);
				}
			}
		}
		else {
			for(int i = 1; i <= n; i++) {
				int temp = row % n;
				if(row % n == 0)temp = n;
				col2[temp] = i;
				if(judge2(temp, i)) {
					dfs(row+1);
				}
			}
		}
	
	}
	
	
	public static boolean judge1(int r, int c) {
		for(int i = 0; i < list.size(); i +=2) {
			if(list.get(i) == r && list.get(i+1) == c) {
				return false;
			}
		}
		
		for(int i = 1; i < r; i++) {
			if(col1[i] == c || (Math.abs(i - r) == Math.abs(col1[i] - c))) return false;
		}
		
		return true;
	}
	
	public static boolean judge2(int r, int c) {
		for(int i = 0; i < list.size(); i +=2) {
			if(list.get(i) == r && list.get(i+1) == c) {
				return false;
			}
		}
		
		for(int i = 1; i < col1.length; i++) {
			if(i == r && col1[i] == c)return false;
		}
		
		for(int i = 1; i < r; i++) {
			if(col2[i] == c || (Math.abs(i - r) == Math.abs(col2[i] - c))) return false;
		}
		
		return true;
	}

完整代码

package Exercise;

import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;

public class towQueens {
	static int n;
	static int[] col1;
	static int[] col2;
	static ArrayList<Integer> list;
	static int count = 0;
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		n = input.nextInt();
		
		col1 = new int[n+1];
		col2 = new int[n+1];
		
		list = new ArrayList<Integer>();
		for(int i = 0; i < n; i++) {
			for(int j =0; j < n;j++) {
				if(input.nextInt() == 0) {
					list.add(i+1);
					list.add(j+1);
				}
			}
		}
	
		dfs(1);
		
		System.out.println(count);
	}

	
	public static void dfs(int row) {
		if(row > 2 * n) {
			
			count++;
			return;
		}
		
		if(row <= n) {
			for(int i = 1; i <= n; i++) {
				col1[row] = i;
				if(judge1(row, i)) {
					dfs(row+1);
				}
			}
		}
		else {
			for(int i = 1; i <= n; i++) {
				int temp = row % n;
				if(row % n == 0)temp = n;
				col2[temp] = i;
				if(judge2(temp, i)) {
					dfs(row+1);
				}
			}
		}
	
	}
	
	
	public static boolean judge1(int r, int c) {
		for(int i = 0; i < list.size(); i +=2) {
			if(list.get(i) == r && list.get(i+1) == c) {
				return false;
			}
		}
		
		for(int i = 1; i < r; i++) {
			if(col1[i] == c || (Math.abs(i - r) == Math.abs(col1[i] - c))) return false;
		}
		
		return true;
	}
	
	public static boolean judge2(int r, int c) {
		for(int i = 0; i < list.size(); i +=2) {
			if(list.get(i) == r && list.get(i+1) == c) {
				return false;
			}
		}
		
		for(int i = 1; i < col1.length; i++) {
			if(i == r && col1[i] == c)return false;
		}
		
		for(int i = 1; i < r; i++) {
			if(col2[i] == c || (Math.abs(i - r) == Math.abs(col2[i] - c))) return false;
		}
		
		return true;
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值