欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

八皇后问题

程序员文章站 2022-04-22 12:09:39
...

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

八皇后问题

解决:

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

检查条件,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;
        }
    }
}