zoukankan      html  css  js  c++  java
  • 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 public class Main {
     3     static int n,count=0;  
     4     static int map[][];  
     5     public static void main(String args[])  
     6     {  
     7         Scanner cn=new Scanner(System.in);  
     8         n=cn.nextInt();  
     9         map=new int[n][n];  
    10         for(int i=0;i<n;i++)  
    11             for(int j=0;j<n;j++)  
    12                 map[i][j]=cn.nextInt();  
    13         Put(0,2);   //假设黑皇后为2 白皇后为3  放了皇后的地方就用2,3表示  ,0表示第0行
    14         System.out.println(count);  
    15     }
    16     /**
    17      * 
    18      * @param t 开始放的下标
    19      * @param s 皇后的类型
    20      */
    21     public static void Put(int t,int s)  
    22     {  
    23         //放完某种类型的皇后了
    24         if(t==n)  
    25         {  
    26             if(s==2)Put(0,3);  //表示之前放的是黑皇后,现在开始放白皇后
    27             else count++;  //因为这会第n个已经放完了,所以方法数量加1
    28             return ;  //此时白皇后也放完了 ,就返回
    29         }  
    30         for(int i=0;i<n;i++)  
    31         {  
    32               
    33             if(map[t][i]!=1)continue; //此处已被不能放皇后或放过皇后则跳出本次循环 
    34             if(Check(t,i,s))map[t][i]=s; //当前遍历后发现位置合适,就把皇后放当前位置
    35             else continue;  //不合适跳过本次循环,查找当前行下一个位置
    36             Put(t+1,s); //此位置放完一个皇后还要去放下一个皇后 
    37             map[t][i]=1;   //回溯法的关键,假设这个位置不放皇后,把皇后放在别的位置   
    38         }  
    39         return ;  
    40     }  
    41     /**
    42      * 
    43      * @param t 当前行
    44      * @param i 当前列
    45      * @param s 皇后的类型
    46      * @return
    47      */
    48     public static boolean Check(int t,int i,int s)  
    49     {  
    50         for(int q=t-1;q>=0;q--)  
    51         {  
    52             //当前列上有同类皇后,就返回false
    53             if(map[q][i]==s)return false;  
    54         }         
    55         for(int q=t-1,w=i-1;q>=0&&w>=0;q--,w--)
    56         {  
    57             //检查主对角线向上方向(前几行)是否处于同类皇后在对角线上
    58             if(map[q][w]==s)return false;  
    59         }  
    60         for(int q=t-1,w=i+1;q>=0&&w<=n-1;q--,w++)  
    61         {  
    62             //检查副对角线向上方向(前几行)是否处于同类皇后在对角线上
    63             if(map[q][w]==s)return false;  
    64         }  
    65         return true;  
    66     }  
    67 }
  • 相关阅读:
    tryparse的用法,^0*[1-9]d*$
    寻找指定的进程然后杀死的代码写法
    P2421 [NOI2002]荒岛野人
    P2568 GCD
    P1445 [Violet]樱花
    P3119 [USACO15JAN]草鉴定Grass Cownoisseur
    P1314 聪明的质监员
    P3811 【模板】乘法逆元
    P3943 星空
    P3225 [HNOI2012]矿场搭建
  • 原文地址:https://www.cnblogs.com/liuwanqiu/p/6500530.html
Copyright © 2011-2022 走看看