八皇后(或n皇后)c++的一种求解实现

/*****************************************************
 *    起因:    在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]==0return;
    
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;
}

 执行结果:

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值