每日算法练习——递归(八皇后问题:EightQueen)

知识补充:

八皇后问题

八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。

摘自wiki百科:https://zh.wikipedia.org/wiki/%E5%85%AB%E7%9A%87%E5%90%8E%E9%97%AE%E9%A2%98

C语言代码实现:

#include <stdio.h>
#include <stdlib.h>

int count =0; // 计数

// 判断危险 
int notDanger(int row, int j , int (*chess)[8] )
{
    int i,k,flag=1;

    // 判断列方向,
    for(i=0; i<8; i++)
    {
        if(i!=row)  //非本皇后(棋子)的位置
        {
            if(*(*(chess+i)+j)!=0)
            {
                flag = 0;
                return flag;
            }
        }
    }
    // 因为是按行放棋子,每行最多一个棋子,所以不需要判断行方向

    // 左上方向
    for(i=row-1,k=j-1; i>=0&&k>=0; i--,k--)
    {
        if(*(*(chess+i)+k)!=0)
        {
            flag = 0;
            return flag;
        }
    }
    // 右下方向
    for(i=row+1,k=j+1; i<8&&k<8; i++,k++)
    {
        if(*(*(chess+i)+k)!=0)
        {
            flag = 0;
            return flag;
        }
    }
    // 右上方向
    for(i=row-1,k=j+1; i>=0&&k<8; i--,k++)
    {
        if(*(*(chess+i)+k)!=0)
        {
            flag = 0;
            return flag;
        }
    }
    // 左下方向
    for(i=row+1,k=j-1; i<8&&k>=0; i++,k--)
    {
        if(*(*(chess+i)+k)!=0)
        {
            flag = 0;
            return flag;
        }
    }

    // 如果上述几个危险检查都通过了返回flag=1
    return flag;
}
// 参数 : 第row行 共n列,
void EightQueen(int row, int n,int (*chess)[8])
{
    int chess2[8][8],i,j;
    for(i=0; i<8; i++)
    {
        for(j=0; j<8; j++)
        {
            chess2[i][j] = chess[i][j];
        }
    }

    if( row == 8 )
    {
        printf("第 %d 种\n",++count);
        for(i=0; i<8; i++)
        {
            for(j=0; j<8; j++)
            {
                printf("%d ",*(*(chess2+i)+j));
            }
            printf("\n");
        }
    }
    else
    {
        for(j=0; j<n; j++)
        {

            if(notDanger(row, j, chess)) //判断第row行第j列的位置是否危险
            {
                for(i=0;i<8;i++)    // 如果不危险,先整行置0,再将第j列的位置置1;
                {
                    *(*(chess2+row)+i) = 0;
                }
                *(*(chess2+row)+j) = 1;
                EightQueen(row+1, n, chess2);
            }

        }
    }

}

int main()
{
    int chess[8][8],i,j;
    for(i=0;i<8;i++)
    {
        for(j=0;j<8;j++)
        {
            chess[i][j]=0;
        }
    }
    // 按行放棋子,从第0行开始
    EightQueen(0,8,chess);

    printf("总共有 %d 种解决方法!!\n",count);
    return 0;
}

wiki百科代码C语言:

简直妙的不行:

#include <stdio.h>

#define QUEENS       8 /*皇后数量*/
#define IS_OUTPUT    1 /*(IS_OUTPUT=0 or 1),Output用于选择是否输出具体解,为1输出,为0不输出*/

int A[QUEENS], B[QUEENS * 3 + 1], C[QUEENS * 3 + 1], k[QUEENS + 1][QUEENS + 1];
int inc, *a = &A[QUEENS], *b = &B[QUEENS], *c = &C[QUEENS];
void lay(int i)
{
    int j = 0, t, u;

    while (++j <= QUEENS)
        if (a[j] + b[j - i] + c[j + i] == 0)
        {
            k[i][j] = a[j] = b[j - i] = c[j + i] = 1;
            if (i < QUEENS)
                lay(i + 1);
            else
            {
                ++inc;
                if (IS_OUTPUT)
                {
                    for (printf("(%d)\n", inc), u = QUEENS + 1; --u; printf("\n"))
                        for (t = QUEENS + 1; --t; )
                            k[t][u] ? printf("Q ") : printf("+ ");
                    printf("\n\n\n");
                }
            }
            a[j] = b[j - i] = c[j + i] = k[i][j] = 0;
        }
}

int main(void)
{
    lay(1);
    printf("%d皇后共计%d个解", QUEENS, inc);
    getchar();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41420747/article/details/81938250