八皇后问题

 

在棋盘上放置8个皇后,使得她们互不攻击,此时每个皇后的攻击范围为同行、同列、同对角线,要求找出所有解,如图所示:

                                   

最简单的思路是把问题转换为“从64个格子中选一个子集”,使得“子集中恰好有8个格子”,且任意两个选出的格子都不在同一行,同一列或同一个对角线上。这正是子集枚举问题。然而,64个格子的子集有2^64个,太大了,这并不是一个很好的模型。

第二个想法是把问题转换成“从64个格子中选8个格子”,这是组合生成问题,根据组合数学,有4.426*10^9种方案,仍然不够好。

经过思考,不难发现以下事实:恰好每行每列放置一个皇后,如果用C[x]表示第x行皇后的列编号,则问题变成了全排列生成问题,而我们知道,0-7的排列一共只有8!=40320个,枚举量不会超过它。

 

下面的程序简洁的求解了八皇后问题。在主程序中读入n,并为tot清零,然后调用search(0),即可得到解的个数tot。

void search(int cur)
{   int i,j;
    if (cur == n) tot++;  /**递归边界,只要走到了这里,所有的皇后必然不冲突*/
    else
    for (i=0 ;i<n; i++)
    {
        int ok=1;
        C[cur]=i;              /**试把第cur行的皇后放在第i列*/
        for (j=0; j<cur ;j++ ) /**检查是否和前面的皇后有冲突*/
            if (C[cur]==C[j] || cur-C[cur]==j-C[j] || cur+C[cur]==j+C[j])
            { ok=0 ; break;}
            if (ok) search(cur+1);
    }
}


注意:既然是逐行放置的,则皇后肯定不会横向攻击,所以只要检查是否纵向或斜向攻击即可。条件cur-C[cur]==j-C[j] || cur+C[cur]==j+C[j]用来判断皇后(cur,C[cur])和(j,C[j])是否在同一条对角线上。

你可能感兴趣的:(算法,ACM)