蓝桥杯 基础训练 BASIC-27 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
 
示例代码:
 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStreamReader;
 4 
 5 public class Main {
 6     private static int n;                      // n*n棋盘,n个黑皇后和n个白皇后
 7     private static int[][] palace;             //棋盘
 8     private static int[] column_num;           //记录每个皇后放的列号
 9     private static int count;                  //统计方案数
10     private static boolean flag = false;
11     
12     public static void main(String[] args) throws NumberFormatException, IOException {
13         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
14         n = Integer.parseInt(br.readLine());
15         palace = new int[n][n];
16         column_num = new int[n];
17         
18         for(int i = 0; i < n; i++){
19             String[] str = br.readLine().split(" ");
20             for(int j = 0; j < n; j++){
21                 palace[i][j] = Integer.parseInt(str[j]);
22             }
23         }
24         
25         place(0);
26         
27         System.out.println(count);
28     }
29     //   放皇后
30     private static void place(int quee) {
31         if(quee == n && !flag){       //如果n个黑皇后已经放置好,将标记置为true,然后放置n个白皇后
32             flag = true;
33             place(0);
34             flag = false;
35         }else if(quee == n && flag){  //如果黑白皇后都已经放置好,则方案数加1
36             count++;
37         }else{
38             for(int column = 0; column < n; column++){   //遍历列
39                 if(palace[quee][column] == 1){           //如果发现此位置为1,即可以放皇后
40                     int  temp = column_num[quee];        //先将之前放置的列号记录下来,如果此时的列位置不能放皇后,则将之前的列号返回
41                     column_num[quee] = column;
42                     if(judge(quee)){                     //判断放置的位置与 放置好的皇后是否右冲突
43                         palace[quee][column] = -1;       //将此时的棋盘位置置为-1
44                         place(quee+1);                   //然后去放下一个皇后
45                         palace[quee][column] = 1;        //若下一个皇后没有放置好,回溯后将之前的-1变为1,即此时的位置允许放皇后
46                     }
47                     column_num[quee] = temp;             //返回列号
48                 }
49             }
50         }
51     }
52     
53     //判断放置的位置与放置好的皇后是否有冲突
54     private static boolean judge(int quee) {
55         for(int ready = 0; ready < quee; ready++){                         //用之前的皇后去检测
56             if(column_num[ready] == column_num[quee] ||                    //是否在同一列
57                quee + column_num[quee] == ready + column_num[ready] ||     //是否在左对角线
58                quee - column_num[quee] == ready - column_num[ready]){      //是否在右对角线
59                 return false;
60             }
61         }
62         return true;
63     }
64 }
原文地址:https://www.cnblogs.com/cao-lei/p/6590033.html