zoukankan      html  css  js  c++  java
  • 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

     
  • 相关阅读:
    java实验二
    实验1
    响应式站点设计之使用指南
    掌管一个网站?给你九条忠告
    在本地App上设计Web代码
    订阅
    下载站焦点图
    个性化电影频道js
    展开收起播放列表
    onoff组件
  • 原文地址:https://www.cnblogs.com/AIchangetheworld/p/12511938.html
Copyright © 2011-2022 走看看