蓝桥杯 2n皇后问题 【递归】

版权声明:记笔记~~~ https://blog.csdn.net/weixin_42765557/article/details/87548144

问题描述

  给定一个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

ways:

和8皇后问题基本一致,可以先安排白皇后,白皇后安排好后再安排黑皇后。

AC代码

#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
int a[9][9],N,ans;
bool book[9][9]; // book[i][j]用来记录第i行第j个位置有没有皇后在 
int col[9][2];	// 第 0 列记录白皇后的位置,第 1 列记录黑皇后的位置 
bool Judge(int x,int y,int k) 	
{
	for(int i=1;i<x;i++) {
		if(col[i][k] == y || abs(i-x) == abs(col[i][k]-y))
			return false;
	}
	return true;
}
void dfs_b(int n)
{

	if(n == N+1) {
		ans++;
		return;
	}
	
	for(int i=1;i<=N;i++) {
		if(a[n][i] && !book[n][i])
			if(Judge(n,i,1)) {
				col[n][1] = i;
				book[n][i] = true;
				dfs_b(n+1);
				book[n][i] = false;
			}
	}	
} 
void dfs_w(int n)
{

	if(n == N+1) {
		dfs_b(1);
		return;
	}
	
	for(int i=1;i<=N;i++) {
		if(a[n][i] && !book[n][i])
			if(Judge(n,i,0)) {
				col[n][0] = i;
				book[n][i] = true;
				dfs_w(n+1);
				book[n][i] = false;
			}
	}	
} 
int main()
{
	cin >> N;
	for(int i=1;i<=N;i++)
		for(int j=1;j<=N;j++)
			cin >> a[i][j];
	
	memset(book,false,sizeof book);
	ans = 0;
	dfs_w(1);
	cout << ans << endl;
}

猜你喜欢

转载自blog.csdn.net/weixin_42765557/article/details/87548144