八皇后問題-遞歸求解

八皇后問題

在國際象棋的棋盤上,按照國際象棋的規則,擺放8個皇后,使之“和平共處”。如圖所示,在3-D上有一個皇后,則綠色區域中都不能再放置皇后了。
最暴力的方法就是使用八個for,但是很明顯,這種方法效率太低。
在這裏插入圖片描述
對於放置了皇后的位置,仔細觀察棋盤可以發現每一列(行)只能有一個皇后,每一個主(次)對角線上也只能有一個皇后,這樣需要標記:行-row,列-col,主對角線-(n+row-col),次對角線-(row+col)

注意:關於對角線的一點說明:
    這裏以次對角線爲例:數字相同的表示一條次對角線,所以對於一個8x8的棋盤來說,一共有2x8-1條次對角線。
在這裏插入圖片描述
流程圖:
在這裏插入圖片描述
基於流程圖,利用遞歸的思想,c++實現如下,這裏的皇后的個數是在主函數中設置的8,個數可以改,但意義不大。。。。。
在遞歸回溯的過程中清空了標記,是爲了繼續搜索,找到所有的解。

#include <iostream>
#include <vector>

using namespace std;

class EightQueen {
public:
	EightQueen(int nQueen) {
		this->nQueen = nQueen;
		inColumn.resize(nQueen, false);
		mainDiagonal.resize(2 * nQueen - 1, false);
		minorDiagonal.resize(2 * nQueen - 1, false);
	}
	~EightQueen() {}
	int process() {
		int *path = new int[nQueen];
		calculate(path, 0);
		delete[] path;
		return 0;
	} 
	void calculate(int *path, int row) {
		if (row == nQueen) {
			solution.push_back(vector<int>(path, path + nQueen));
			return;
		}
		for (int col = 0; col < nQueen; col++) {
			if (canLay(row, col)) {//當前位置可放置
				path[row] = col;//標記放置的位置
				inColumn[col] = true;//當前皇后所在列
				minorDiagonal[row+col] = true;//皇后所在位置的橫縱座標之和對應的次對角線
				mainDiagonal[nQueen-1+row-col] = true;//皇后所在位置的橫縱座標之和對應的主對角線
				calculate(path, row + 1);//下一行上的皇后
				//break;//去掉搜索所有的解!
				inColumn[col] = false;
				minorDiagonal[row+col] = false;
				mainDiagonal[nQueen-1+row-col] = false;
			}
		}
	}
	bool canLay(int row, int col) {
		return !inColumn[col] && !minorDiagonal[row + col] && !mainDiagonal[nQueen - 1 + row - col];
	}
	void print() {
		for (int i = 0; i < solution.size(); i++) {
			cout << "solution " << i << " : " << endl;
			for (int row = 0; row < nQueen; row++) {
				for (int col = 0; col < solution[i][row]; col++) {
					cout << "O ";
				}
				cout << "X ";
				for (int col = solution[i][row]+1; col < nQueen; col++) {
					cout << "O ";
				}
				cout << endl;
			}
			cout << endl << endl;
		}
	}
private:
	int nQueen;
	vector<bool> inColumn;
	vector<bool> mainDiagonal;
	vector<bool> minorDiagonal;
	vector<vector<int> > solution;
};

int main()
{
	EightQueen queen(8);
	queen.process();
	queen.print();
	return 0;
}

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