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;
}
全部代码:
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;
}
}
结果
进阶版
问题描述
给定一个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;
}
}