八皇后问题

引言:在棋盘上放置八个皇后,使得他们互相不攻击,攻击范围为同行同列,同对角线。


解决:

逐行放置,检查当前皇后所放的列,是否和已放皇后的列和对角线有冲突。

检查条件,cur-C[cur]==j-C[j] || cur+C[cur]==j+C[j],用来判断皇后(cur,C[cur])(j,C[j])是否在同一条对角线上。

原理图:

                                                              

(a)格子(x,y)的y-x值标识了主对角线               (b)格子(x,y)的x+y值标识了副对角线


代码:
void searchs(int cur)
{
   int i,j;
   if(cur==n) tot++;///计算有多种可能的结果
   else for(int i=0;i<n;i++)
   {
       int ok=1;
       C[cur]=i;
       for(int j=0;j<cur;j++){ ///检查前cur-1行是否已第cur行有无冲突
        if(C[cur]==C[j]||cur-C[cur]==j-C[j]||cur+C[cur]==j+C[j]){
            ok=0;break;
        }
       }
       if(ok) searchs(cur+1); ///递归下一行
   }
}

除了上述的判断外,还可以利用二维数组vis[2][ ]直接判断当前尝试的皇后所在的列和两个对角线是否已有其他皇后

注意到主对角线标识y-x可能为负,存取时可加上n。

代码:

void searchs(int cur)
{
    int i,j;
    if(cur==n) tot++;
    else for(int i=0;i<n;i++)
    {
        if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n])
        {
            C[cur]=i;
            vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1;
            searchs(cur+1);
            vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值