Java解决八皇后问题

Java解决八皇后问题

基础版

给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个皇后,使任意的两个皇后都不在同一行、同一列或同一条对角线上。

题解主要由两步构成:

1.放置棋子

static void putChess(int n){//n代表第几个棋子
	if(n == chessColPos.length) {
		print();//用来打印放置情况
		return;
	}
	
	for (int i = 0; i < chessColPos.length; i++) {
		chessColPos[n] = i;//chessColPos是一个用来放置棋子位置的数组,比如chessColPos[1] = 2,是指第二个棋子放在了第三个列上,注意要从0开始计数
		if(judge(n)) {//判断这个棋子放的对不对
			putChess(n+1);//如果放对了就放下一个棋子
		}
        //如果没有放对,就进入下一轮循环,试试下一列(就是i)能不能放
	}
	
}

2.判断棋子是否能够放置

static boolean judge(int n){
		for (int i = 0; i < n; i++) {
            //判断一下前面的棋子和现在这个棋子的位置关系
            //chessColPos[n]==chessColPos[i]用来判断是不是在同一列,chessColPos数组用来存储棋子放在了第几列,索引为第几个棋子,值为第几列
            //Math.abs(n-i)==Math.abs(chessColPos[n]-chessColPos[i])用来判断是不是在对角线
			if(chessColPos[n]==chessColPos[i]||Math.abs(n-i)==Math.abs(chessColPos[n]-chessColPos[i])) {
				return false;
			}
		}
		return true;
	}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CKtJhYEX-1616213393115)(C:\Users\MoFish\AppData\Roaming\Typora\typora-user-images\image-20210320111443098.png)]

全部代码:

public class Main2 {
	
	static int []chessColPos;
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int size = scanner.nextInt();
		chessColPos = new int[size];
	
		for (int n = 0; n < size; n++) {
			putChess(n);
		}
		
		scanner.close();
		
	}
	
	static void putChess(int n){
		if(n == chessColPos.length) {
			print();
			return;
		}
		
		for (int i = 0; i < chessColPos.length; i++) {
			chessColPos[n] = i;
			if(judge(n)) {
				putChess(n+1);
			}
		}
		
	}
	
	private static void print() {
		System.out.println(Arrays.toString(chessColPos));
		
	}

	static boolean judge(int n){
		for (int i = 0; i < n; i++) {
			if(chessColPos[n]==chessColPos[i]||Math.abs(n-i)==Math.abs(chessColPos[n]-chessColPos[i])) {
				return false;
			}
		}
		return true;
		
		
	}

}

结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4RiNlaRZ-1616213393117)(C:\Users\MoFish\AppData\Roaming\Typora\typora-user-images\image-20210320100502320.png)]

进阶版

问题描述

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

输入格式

输入的第一行为一个整数n,表示棋盘的大小。
  接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。

输出格式

输出一个整数,表示总共有多少种放法。

样例输入

4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1

样例输出

0

主要是对基础版进行三处修改

1.修改第一种皇后的放置规则

在judge方法中加入

		if(board[n][chessColPos[n]]!=1) {
			return false;
		}

board是个二维数组,代表题目要求输入的棋盘,不是1的位置代表不能放置棋盘

2.放好第一种皇后之后去放置第二种皇后

在putChess方法中修改完成放置后的操作,putOtherChess方法仿照putChess写即可

		if(n == chessColPos.length) {
//			System.out.println("The first is:");
//			print(chessColPos);
			putOtherChess(0);
			return;
		}

3.修改放置第二种皇后的judge规则

在以前的judge中加入

		if(chessColPos2[n]==chessColPos[n]) {
			return false;
		}

第一种皇后已经占走的位置第二种皇后不能再去占领

全部代码

public class Main2 {
	
	static int []chessColPos;
	static int []chessColPos2;
	static int [][] board;
	public static int  sum = 0 ;
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int size = scanner.nextInt();
		chessColPos = new int[size];
		chessColPos2 = new int[size];
		board = new int[size][size];
		for (int i = 0; i < board.length; i++) {
			for (int j = 0; j < board.length; j++) {
				board[i][j] = scanner.nextInt();
			}
		}
		putChess(0);
		System.out.println(sum);
		scanner.close();
		
	}
	
	static void putChess(int n){
		if(n == chessColPos.length) {
//			System.out.println("The first is:");
//			print(chessColPos);
			putOtherChess(0);
			return;
		}
		
		for (int i = 0; i < chessColPos.length; i++) {
			chessColPos[n] = i;
			if(judge(n)) {
				putChess(n+1);
			}
		}
		
	}
	
	private static void putOtherChess(int n) {
		if(n == chessColPos2.length) {
//			System.out.println("The other side is");
//			print(chessColPos2);
			sum++;
			return;
		}
		
		for (int i = 0; i < chessColPos2.length; i++) {
			chessColPos2[n] = i;
			if(judgeOther(n)) {
				putOtherChess(n+1);
			}
		}
		
	}



	private static void print(int [] tempChessColPos) {
		System.out.println(Arrays.toString(tempChessColPos));
		
	}

	static boolean judge(int n){
		for (int i = 0; i < n; i++) {
			if(chessColPos[n]==chessColPos[i]||Math.abs(n-i)==Math.abs(chessColPos[n]-chessColPos[i])) {
				return false;
			}//chessColPos[n]
		}
		if(board[n][chessColPos[n]]!=1) {
			return false;
		}
		return true;
	}
	
	private static boolean judgeOther(int n) {
		
		for (int i = 0; i < n; i++) {
			if(chessColPos2[n]==chessColPos2[i]||Math.abs(n-i)==Math.abs(chessColPos2[n]-chessColPos2[i])) {
				return false;
			}//chessColPos[n]
		}
		if(board[n][chessColPos2[n]]!=1) {
			return false;
		}
		if(chessColPos2[n]==chessColPos[n]) {
			return false;
		}
		
		return true;
	}

}

结果

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值