Sicily. 八皇后問題


Description

給定一個8*8棋盤,要求在棋盤上放8個皇后,並且各個皇后之間不能相互攻擊。 
當兩個皇后位於同一行或同一列或同一對角線(有兩條)就會相互攻擊。 
現在要求大家編程輸出8皇后問題的所有解。 

注意:皇后是逐行放的,也就要求輸出每一行放皇后的列號的序列,行號和列號都是從1開始的

Input

Output

每一行輸出一個解決方案; 要求輸出所有方案。
每個解決方案是列號的序列,列號之間以空格隔開,行尾無多餘空格。 

行號和列號都是從1開始的

Sample Output
1 5 8 6 3 7 2 4
1 6 8 3 7 4 2 5
...


八皇后問題,經典問題。
深搜+回溯。

#include<iostream>
#include<stdio.h>
#include<cmath>
#include<vector>

using namespace std;

void dfs(vector<int>& queen, bool used[]) {
	  //  形成了一個解法,輸出答案。
	if (queen.size() == 8) {

		for (int i = 0; i < 7; i++)
			printf("%d ", queen[i]);

		printf("%d\n", queen[7]);
		
		return;
	}

	for (int i = 1; i <= 8; i++) {
		  //  如果該列數已經用過,則跳過
		if (used[i])
			continue;

		  //  判斷該列如果放置皇后,對角線是否形成攻擊
		bool diagonalOK = true;
		  //  遍歷當前已放置了皇后的位置j
		for (int j = 0; j < queen.size(); j++) {
			//  A、B兩個位置,如果A與B的行數之差,等於A與B的列數之差,則A與B一定在一條對角線上
			//  queen.size() - j是兩個位置的行數之差,abs(i - queen[j])是兩個位置的列數之差
			if (queen.size() - j == abs(i - queen[j])) {
				diagonalOK = false;
				break;
			}
		}

		  //  深搜與回溯
		if (diagonalOK) {
			queen.push_back(i);
			used[i] = true;

			dfs(queen, used);
			
			queen.pop_back();
			used[i] = false;
		}
	}
}

int main() {
	vector<int> queen;  //  存儲解法的容器
	bool used[9] = {0};  //  標記列數是否已用過(1~8)
	
	dfs(queen, used);

	return 0;
}


最終的解一共92個。



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