在国际象棋的规则中,皇后能够吃掉与自己位于同一行、同一列或同一对角线的其他皇后,而问题的解决是要实现将N个皇后放入N*N的棋盘上使之共存。
使用回溯法,通过构造部分解,并在保证部分解满足条件的前提下继续探求其他可能的部分解。而递归的使用可以使得这一方法重复进行直到满足条件的个别皇后位置的出现。
C++代码如下:
#include<iostream>
using namespace std;
const int max_board = 20;//全局常量,最大的皇后数
class Queens {
public:
Queens(int size);
bool is_solve()const; //检查是否完成一个解
void print()const;//打印结果
bool unguarded(int col) const; //检查当前皇后是否满足条件
void insert(int col); //插入一个皇后
void remove(int col); //上溯,移除不满足的皇后
int board_size; //皇后数
private:
int count; //记录行数
bool queen_square[max_board][max_board];
};
void Queens::insert(int col) {
queen_square[count++][col] = true;
}
bool Queens::is_solve() const {
if(count == board_size) return true;
else return false;
}
void Queens::remove(int col) {
queen_square[count-1][col] = false;
count--;
}
void Queens::print() const{
cout << endl<<endl;
for( int i = 0; i < board_size; ++i) {
for( int j = 0; j < board_size; ++j) {
if(queen_square[i][j])
cout << "Q ";
else
cout << "+ ";
}
cout << endl;
}
}
Queens::Queens(int size) {
board_size = size;
count = 0;
for( int row = 0; row < board_size; row++)
for( int col = 0; col < board_size; col++)
queen_square[row][col] = false;
}
bool Queens::unguarded(int col) const{
int i;
bool ok=true;
for( i = 0; ok&&i < count; i++)
ok = !queen_square[i][col];
for(i = 1; ok&&count - i >= 0 && col - i >= 0; i++)
ok = !queen_square[count-i][col-i];
for(i = 1; ok&& count - i >= 0 && col + i < board_size; i++)
ok = !queen_square[count-i][col+i];
return ok;
}
void solve_from( Queens &configuration) {
if(configuration.is_solve()) configuration.print();
else {
for(int col = 0; col < configuration.board_size; ++col)
if(configuration.unguarded(col)) {
configuration.insert(col);
solve_from( configuration );
configuration.remove(col);
}
}
}
int main() {
int board_size;
//print_information();
cout << "what is the size of the board?"<<endl;
cin >> board_size;
if( board_size < 0|| board_size > max_board)
cout << "the number must be between 0 and 10" << max_board << endl;
else {
Queens configuration(board_size);
solve_from(configuration);
}
return 0;
}
基于unguarded( )成员函数的算法还可以继续优化,以降低时间复杂度。