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  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章