算法笔记 —— 八皇后问题

一. 问题描述

在国际象棋中,皇后棋子拥有最大的攻击力ju,她除了可以像象棋中的‘车’一样攻击行和列,还可以攻击四个斜方向的棋子,如图:
在这里插入图片描述
红线为其攻击范围,那么什么是八皇后问题呢?
即在当前棋盘上,要摆放八个皇后棋子,且这八个皇后棋子,不能在彼此的攻击范围内,例如下面这种情况:
在这里插入图片描述

二. 思路分析

在第一行放置一颗棋子,来到第二行,放置棋子时,需要判断这个位置是否危险,即该位置的列方向,斜方向是否有其他棋子存在(因为行方向只能放一颗棋子),如果安全,则放下棋子,递归调用函数,直到第八颗棋子放置完毕后,打印棋盘目前的状况

三. 代码

#include <stdio.h>

int count = 1;

int notdanger(int row,int j,int (*chess)[8])
{
    int i,k;
    int flag1 = 0,flag2 = 0,flag3 = 0,flag4 = 0,flag5 = 0;

    for(i = 0; i < 8; i++) //判断列方向是否有棋子
    {
        if( *(*(chess+i)+j) != 0 )
        {
            flag1 = 1;
            break;
        }
    }

    for(i = row,k = j; i >= 0 && k >= 0; i--,k--) //判断左上方是否有棋子
    {
        if(  *(*(chess+i)+k) != 0)
        {
            flag2 = 1;
            break;
        }
    }

    for(i = row,k = j; i < 8 && k < 8; i++,k++) //判断右下方是否有棋子
    {
        if(  *(*(chess+i)+k) != 0)
        {
            flag3 = 1;
            break;
        }
    }

    for(i = row,k = j; i >= 0 && k < 8; i--,k++) //判断右上方是否有棋子
    {
        if(  *(*(chess+i)+k) != 0)
        {
            flag4 = 1;
            break;
        }
    }

    for(i = row,k = j; i < 8 && k >= 0; i++,k--) //判断左下方是否有棋子
    {
        if(  *(*(chess+i)+k) != 0)
        {
            flag5 = 1;
            break;
        }
    }

    if(flag1 || flag2 || flag3 || flag4 || flag5)
    {
        return 0;
    }
    else 
    {
        return 1;
    }
}

void EightQueens(int row,int n,int (*chess)[8])  //row表示当前进行到第几行,n便是列数,chess表示指向某一行的指针
{
    int chess_temp[8][8],i,j;

    for(i = 0; i < 8; i++)
    {
        for(j = 0; j < 8; j++)
        {
            chess_temp[i][j] = chess[i][j];
        }
    }

    if( 8 == row )  //递归结束
    {
        printf("第%d种\n",count++);

        for(i = 0; i < 8; i++)
        {
            for(j = 0; j < 8; j++)
            {
                printf("%d ",*(*(chess_temp+i)+j));
            }
            printf("\n");
        }
        printf("\n");
    }
    else 
    {
        for(j = 0; j < n; j++) 
        {
            if( notdanger(row,j,chess))
            {
                for(i = 0; i < 8; i++)
                {
                    *(*(chess_temp+row)+i) = 0;  //将这一行的所有位置赋值为0
                }
                *(*(chess_temp+row)+j) = 1;  //将这个位置赋值1

                EightQueens(row+1,n,chess_temp);  //递归调用
            }
        }
    }

}

int main(int argc, char *argv[])
{
    int chess[8][8] = {0};

    EightQueens(0,8,chess);
    
    
    
    return 0;
}

四. 运行结果

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章