K-N皇后问题,回溯法、BFS、DFS,任意数量种类的皇后在棋盘上的摆放方案

对最大为MAX*MAX的棋盘,任意数量种的皇后,种类数量以queen记录,每种皇后的同一行,同一列,以及对角线上不能有其他同种类的皇后,一个格子只能放一个皇后棋子,计算最多摆放方案的数量,并记录在ans[][]内,输出方案数量。

判断对角线用

abs(行-行) == abs(列-列)

后续再更新优化,用二进制保存数据判断运算。

#include <iostream>
#include <cmath>
#include <cstring>
#define MAX 13//棋盘最大范围 
#define queen 2//两种棋 

using namespace std;

int N;
int rst = 0;
bool map[MAX][MAX];
int ans[queen][MAX];

void test(){//测试数据
	N = 13;
	for(int i = 0; i < N; ++i){
		for(int j = 0; j < N; ++j){
			map[i][j] = 1;
		}
	} 
}

void inputData(){
	cin >> N;
	for(int i = 0; i < N; ++i){
		for(int j = 0; j < N; ++j){
			cin >> map[i][j];
		}
	}
}

bool check(int row, int column, int chess){
	if(map[row][column] == 1){
		for(int i = 0; i < chess; ++i){
			if(ans[i][row] == column){
				return 0;
			}
		}
		for(int i = 0; i < row; ++i){
			if(ans[chess][i] == column){//判断同列
				return 0;
			}
			if(abs(i - row) == abs(ans[chess][i] - column)){//判断对角线
				return 0;
			}
		}
		return 1;//能放
	}else{
		return 0;//不能放
	}
}

void dfs(int row, int chess){
	if(row == N){
		if(chess == queen-1){
			rst++;
			cout << rst << endl; 
		}else{
			dfs(0, chess + 1);
		}
	}
	for(int column = 0; column < N; ++column){
		if(!check(row, column, chess)){ 
			continue;
		}else{
			ans[chess][row] = column;//记录每种棋在每几行的列数
			dfs(row+1, chess);
		}
	}
}

int main(){
	test();
	dfs(0, 0);//第0种棋的第0行开始 
	cout << rst; 
	return 0;
}

ps:一种棋时,各大小棋盘的解数量

n       solution(n)  
1       1  
2       0  
3       0  
4       2  
5       10  
6       4  
7       40  
8       92  
9       352  
10      724  
11      2680  
12      14200  
13      73712  
14      365596  
15      2279184  
16      14772512  
17      95815104  
18      666090624  
19      4968057848  
20      39029188884  
21      314666222712  
22      2691008701644  
23      24233937684440  
24      227514171973736  
25      2207893435808352  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值