14_栈的递归实例5---8皇后问题

来源:互联网 发布:为什么ofo网络异常 编辑:程序博客网 时间:2024/06/03 17:42

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。

#include <iostream>using namespace std;#define N 8 using Pos = struct _tag_pos {    int ios;    int jos;};static char board[N + 2][N + 2];/*设置对角线,同一列的偏移量*/static Pos pos[] = { {-1,-1},{-1,0},{-1,+1} };void display() {    for (int i = 0; i < N + 2; ++i ) {        for (int j = 0; j < N + 2; ++j ) {            cout << board[i][j];        }        cout << endl;    }}void init() {    for (int i = 0; i < N + 2; ++i ) {        board[0][i] = '#';        board[N + 1][i] = '#';        board[i][0] = '#';        board[i][N + 1] = '#';    }    for (int i = 0; i < N; ++i ) {        for (int j = 0; j < N; ++j ) {            board[i+1][j+1] = ' ';        }    }}/*检查这个(i,j)点能否放下棋子*/bool check( int i , int j ) {     bool flag = true ;    for (int p = 0; p < 3; ++p ) {        int ni = i;        int nj = j;        while ( flag && (board[ni][nj]!='#') ) {            ni = ni + pos[p].ios;            nj = nj + pos[p].jos;            flag = flag && (board[ni][nj]!='*');        }    }    return flag ;}/*查看第i行的某一列j能否放下棋子*/void find( int i ) {    if ( i>N ) {        display();        getchar();    }    else {        /*假设现在在第i行,就从这一行的头到尾依次检测是否能放下棋子*/        for (int j = 1; j <= N; ++j ) {            if ( check(i,j) ) {                board[i][j] = '*';                find(i+1);/*如果第i行能放下棋子,就查看第i+1行能否放下棋子*/                board[i][j] = ' ';            }        }    }}int main( int argc , char *argv[] ) {    init();    find( 1 );    return 0;}