/**/ /***************************************************** * 起因: 在c++社区看见有人问如何以简洁高速地方式解决八皇后(或n皇后)问题 * * 问题描述:n*n棋盘,放n个皇后互不相吃(任何两个皇后不同行不同列不同45度斜),输出所有组合。 * * 思路: 采用范围缩小搜索法:在第1行放一个棋子,则第2到n行能放棋子的地方因此受限,标记之; * 在第2行能放棋子的地方放下棋子,则第3到n行能放棋子的地方进一步受限,添加标记; * 依次类推,如某行全部标记为不能放,回退到上一行重新放子。以此搜索所有可行方案。 * * 算法: 充分利用位操作,为增加可扩展性,使用c++提供的bitset类。 * 用数组sts[n]表示每行自由位置(皇后可放的位置)。 * 如第一行为sts[0]=111101...11则表示第一行除了5号位可放外,其余位置都不能放(0表示可放,1表示不可放) * 显然如果某行出现sts[x]=1111111...11(全1)则说明这种放置方法失败,需要回退。 * * 编译环境:VC6.0 * ****************************************************/ #include < iostream > #include < bitset > using namespace std; #define N 8 int pos[N];bitset < N > sts[N];bitset < N > mask[N][N]; int count; /**/ /*输出结果*/ void print() ... { int i,j; cout<<endl; for(i=0;i<N;i++)...{ for(j=0;j<pos[i];j++) cout<<" . "; cout<<" O "; for(j=pos[i]+1;j<N;j++) cout<<" . "; cout<<endl; }} /**/ /*搜索第归*/ void queen( int n) ... { int i,j; if(~sts[n]==0) return; for(i=0;i<N;i++)...{ if(!sts[n].test(i))...{ pos[n]=i; if(n+1==N)...{//成立 print();count++; return; } for(j=n+1;j<N;j++)...{ mask[n][j]=sts[j]; sts[j].set(i); if(i+j-n<N) sts[j].set(i+j-n); if(i+n-j>=0) sts[j].set(i+n-j); } queen(n+1); for(j=n+1;j<N;j++) sts[j]&=mask[n][j];//回退 } }} int main( int argc, char * argv[]) ... { int i,j; count=0; for(i=0;i<N;i++) sts[i].reset(); for(i=0;i<N;i++) for(j=0;j<N;j++) mask[i][j].reset(); cout<<"result is:"; queen(0); cout<<"总共有"<<count<<"种排法"<<endl; return 0;} 执行结果: