2N皇后

Posted solitude-cosmos

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2N皇后相关的知识,希望对你有一定的参考价值。

Description

给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。

Input

输入的第一行为一个整数n,表示棋盘的大小。  接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。

Output

输出一个整数,表示总共有多少种放法。

Sample Input 1 

4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1

Sample Output 1

2

Sample Input 2 

4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1

Sample Output 2

0

Solution

n皇后问题的升级版,其实就是考虑了位置能不能下,一方摆完之后换另一个。一边dfs完另一边dfs。

#include<cstdio>
#include<cmath>
using namespace std;

int n;
int count = 0;
int a[20][20];
int location_black[20], location_white[20];

int valid_white(int row, int col) {
  for (int i = 1;i <= row - 1;i++) {
    if (col == location_white[i] || abs(row - i) == abs(col - location_white[i])) {
      return 0;
    }
  }
  return 1;
}

int valid_black(int row, int col) {
  for (int i = 1;i <= row - 1;i++) {
    if (col == location_black[i] || abs(row - i) == abs(col - location_black[i])) {
      return 0;
    }
  }
  return 1;
}

void dfs_black(int row) {
  if (row == n + 1) {
    count++;
    return;
  }
  else {
    for (int i = 1;i <= n;i++) {
      if (a[row][i] == 0||i==location_white[row]) {
        continue;
      }
      else if(valid_black(row, i)) {
        location_black[row] = i;
        dfs_black(row + 1);
      }
    }
  }
}

void dfs_white(int row) {
  if (row == n + 1) {
    dfs_black(1);
    return;
  }
  else {
    for (int i = 1;i <= n;i++) {
      if (a[row][i] == 0) {
        continue;
      }
      if (valid_white(row, i)) {
        location_white[row] = i;
        dfs_white(row + 1);
      }
    }
  }
}

int main() {
  int i, j;
  scanf("%d", &n);
  for (i = 1;i <= n;i++) {
    for (j = 1;j <= n;j++) {
      scanf("%d", &a[i][j]);
    }
  }
  dfs_white(1);
  printf("%d ", count);
  return 0;
}

 

以上是关于2N皇后的主要内容,如果未能解决你的问题,请参考以下文章

n皇后问题与2n皇后问题

2n皇后问题

试题 基础练习 2n皇后问题

2N皇后

2N皇后问题

蓝桥杯 2n皇后问题