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

    import java.util.*;
    
    public class Main {
        static int ans, n;
        static int board[][];
        static int[] c;
    
        static void BlackMap(int row) {
            if (row == n) {
                int board1[][] = new int[n][n];
                for (int i = 0; i < n; i++)
                    for (int j = 0; j < n; j++) board1[i][j] = board[i][j];
    
                for (int i = 0; i < n; i++) board1[i][c[i]] = 0;
                int c1[] = new int[n];
                WhiteMap(0, board1, c1);
            } else///开始放置黑皇后,不要去掉else,否则数组报错
            {
                for (int i = 0; i < n; i++) {
                    if (board[row][i] == 0) continue;
                    boolean ok = true;
                    c[row] = i;
                    for (int j = 0; j < row; j++) {
                        if (c[row] == c[j] || row - c[row] == j - c[j] || row + c[row] == j + c[j]) {
                            ok = false;
                            break;
                        }
                    }
                    if (ok) BlackMap(row + 1);///递归下一行
                }
            }
        }
    
        static void WhiteMap(int row, int board1[][], int c1[]) {
            if (row == n) ans++;///黑白皇后都放置成功
            else {
                for (int i = 0; i < n; i++) {
                    if (board1[row][i] == 0) continue;
                    boolean ok = true;
                    c1[row] = i;///把白皇后放置在row行c1[row]列
                    for (int j = 0; j < row; j++) {///不等于row不同行
                        if (c1[row] == c1[j] || row - c1[row] == j - c1[j] || row + c1[row] == j + c1[j]) {
                            ///判断是否同列,是否同左对角线(其行列值之差为0),是否同右对角线(其行列值之和相等)
                            ok = false;
                            break;
                        }
                    }
                    if (ok) WhiteMap(row + 1, board1, c1);
                }
            }
        }
    
       public static void main(String [] args) {
           Scanner sc = new Scanner(System.in);
           n = sc.nextInt();
           ans=0;
           c=new int[n];
           board=new int[n][n];
           for(int i=0;i<n;i++)
               for(int j=0;j<n;j++) board[i][j]=sc.nextInt();
          BlackMap(0);
          System.out.println(ans);
       }
    }
    

      

    不忘初心,方得始终。只有走过弯路,才更确信当初最想要的是什么。
  • 相关阅读:
    leetcode-15 三数之和
    leetcode-113 路径之和
    leetcode-112 路径之和
    leetcode-1 两数之和
    leetcode-215 第k大元素
    leetcode 698 集合k划分
    编程之法之字符串
    LeetCode 830. Positions of Large Groups
    LeetCode 821. Shortest Distance to a Character
    LeetCode 213. House Robber II
  • 原文地址:https://www.cnblogs.com/wszhu/p/12595842.html
Copyright © 2011-2022 走看看