算法筆記 —— 八皇后問題

一. 問題描述

在國際象棋中,皇后棋子擁有最大的攻擊力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;
}

四. 運行結果

在這裏插入圖片描述

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