2n皇后问题

蓝桥杯基础练习:2n皇后问题

问题描述
  给定一个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.util.Scanner;
 2 
 3 public class Main{
 4     static int n,success; //n表示棋盘的长度,success表示放置成功的次数(即要输出的结果)
 5     static int[] Column1; //一维数组C表示皇后在每行放置的位置
 6     static int[][] board;//表示棋盘
 7     
 8     static void search(int row){//放置黑皇后
 9         if(row==n) { //递归边界,如果row等于n,那么所有皇后必然不会冲突
10 
11             int[][] board1 = new int[n][n]; //生成新棋盘
12             for(int i=0;i<n;i++){
13                 for(int j=0;j<n;j++)
14                     board1[i][j] = board[i][j];
15             }
16             for(int i=0;i<n;i++){//将黑皇后所在位置更新为“0”
17                 board1[i][Column1[i]]=0;
18             }
19 
20             int[] Column2 = new int[n]; 
21             search1(0,board1,Column2);//放置白皇后
22             
23         }else{
24             for(int i=0;i<n;i++){
25                 if(board[row][i] == 0) continue;//如果此位置为“0”,则跳过此次循环
26                 Column1[row] = i;//将第row行的皇后放在第i列
27                 boolean book = true;
28                 for(int j=0;j<row;j++){
29                     if(Column1[row] == Column1[j] || row-Column1[row] == j-Column1[j] || row+Column1[row]==j+Column1[j]){//判断皇后是否冲突
30                         book = false;
31                         break;//冲突则结束此次循环
32                     }
33                     
34                 }
35                 if(book)    search(row+1);//不冲突,则继续进行递归
36             }
37         }
38     }
39     
40     static void search1(int row,int[][] board1,int[] Column2){//放置白皇后
41         if(row==n) 
42             success++;//黑皇后和白皇后都放置成功,success+1
43         else{
44             for(int i=0;i<n;i++){
45                 if(board1[row][i] == 0) continue;
46                 Column2[row] = i;
47                 boolean book = true;
48                 for(int j=0;j<row;j++){
49                     if(Column2[row] == Column2[j] ||row-Column2[row] == j-Column2[j] || row+Column2[row]==j+Column2[j]){
50                         book = false;
51                         break;
52                     }
53                     
54                 }
55                 if(book)    search1(row+1,board1,Column2);
56             }
57         }
58     }
59     
60     public static void main(String[] args){
61         Scanner sc = new Scanner(System.in);
62         success = 0;
63 
64         n = sc.nextInt();//录入棋盘数据
65         Column1 = new int[n];
66         board = new int[n][n];
67         for(int i=0;i<n;i++){
68             for(int j=0;j<n;j++){
69                 board[i][j] = sc.nextInt();
70             }
71         }
72         
73         search(0);
74         System.out.println(success);
75         
76     }
77 }
View Code

思路:递归;需要添加一个一维数组用来记录棋盘放置的位置,数组下标是原棋盘上的行坐标,数组的值是原棋盘上的纵坐标。

对于“使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上”的解决:

  如果将整个的棋盘看成一个坐标系,那么对角线方程就是y = kx+b,k只可能取1或-1,所以只需要判断两个位置的横纵坐标差值相等(均为b,不重要),即可判断两个位置是在同一条对角线,就不满足条件。

 

求八皇后总共有多少个解法?使用DFS搜索。

 1 public class Main {
 2     static int ans = 0;
 3     static boolean[] col = new boolean[10];
 4     static boolean[] x1 = new boolean[20];
 5     static boolean[] x2 = new boolean[20];
 6     public static void main(String args[]){
 7         dfs(0);
 8         System.out.println(ans);
 9     }
10     
11     private static void dfs(int r){
12         if(r == 8){
13             ans++;
14             return;
15         }
16         for(int i=0;i<8;i++){
17             if(check(r,i)){
18                 col[i] = x1[r+i] = x2[r-i+8] = true;
19                 dfs(r+1);
20                 col[i] = x1[r+i] = x2[r-i+8] = false;
21             }
22         }
23     }
24     
25     private static boolean check(int r,int i){
26         return !col[i] && !x1[r+i] && !x2[r-i+8];
27     }
28 
29 }
View Code

答案是:92

 
posted @ 2020-03-17 17:12  AI未来10Y  阅读(363)  评论(0编辑  收藏  举报