2n皇后问题
问题描述
输入格式
输入的第一行为一个整数n,表示棋盘的大小。
接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。
接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。
输出格式
输出一个整数,表示总共有多少种放法。
样例输入
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
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
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1
样例输出
0
import java.util.Scanner; public class Main { /** * 2n皇后问题 *zyj */ static int[][] a; static int n, count = 0; public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc = new Scanner(System.in); n = sc.nextInt(); a = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { a[i][j] = sc.nextInt(); } } put(0, 2);//第一个参数行数第二个参数2代表黑皇后 System.out.println(count); } private static void put(int t, int s) { //判断最后一行放完 if (t == n) { //判断那个皇后放完了 if (s == 2) put(0, 3);//第一个参数行数第二个参数3代表白皇后 else { count++;//放完所有皇后次数+1 } //放完return return; } //遍历每一行所有格格 for (int i = 0; i < n; i++) { //格格不等于1不能放皇后 if (a[t][i] != 1) continue; //判断对角线同列是否有相同皇后 if (isf(t, i, s)) { a[t][i] = s; } else continue; //行+1,防止同行有相同皇后继续放下一行 put(t + 1, s); //回溯回来放过皇后的位置=1,保证测试其他方法还可以再放皇后 a[t][i] = 1; } return; } /* * 判断对角线同列是否有相同皇后的方法 */ private static boolean isf(int t, int i, int s) { //判断同列是否有相同皇后 for (int k = t - 1; k >= 0; k--) { if (a[k][i] == s) { return false; } } //判断左上角是否有相同皇后 for (int k = t - 1, l = i - 1; k >= 0 && l >= 0; k--, l--) { if (a[k][l] == s) { return false; } } //判断右上角是否有相同皇后 for (int k = t - 1, l = i + 1; k >= 0 && l < n; k--, l++) { if (a[k][l] == s) { return false; } } //若没有相同皇后则可以放皇后 return true; } }