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

     
  • 相关阅读:
    Step by step Dynamics CRM 2013安装
    SQL Server 2012 Managed Service Account
    Step by step SQL Server 2012的安装
    Step by step 活动目录中添加一个子域
    Step by step 如何创建一个新森林
    向活动目录中添加一个子域
    活动目录的信任关系
    RAID 概述
    DNS 正向查找与反向查找
    Microsoft Dynamics CRM 2013 and 2011 Update Rollups and Service Packs
  • 原文地址:https://www.cnblogs.com/techgy/p/12511938.html
Copyright © 2011-2022 走看看