利用递归求解八皇后问题

利用递归求解八皇后此类问题。

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

#define ROW 8  //8行 修改行数、列数,可求解对应的N皇后问题
#define COLUMN 8  //8列

int notDanger(int row,int column,int (*chess)[]);
void EightQueen(int row,int column,int (*chess)[]);

int count=0; //记录解的个数

int main(int agrc,char *argv[])
{
    int i,j;
    int chess[ROW][COLUMN]; //初始化八皇后问题棋盘。
    for(i=0;i<ROW;i++)
    {
        for(j=0;j<COLUMN;j++)
        {
            chess[i][j]=0;
        }
    }
	//从第一行开始,求解八皇后问题
    EightQueen(0,COLUMN,chess);
    exit(0);
}

/*
八皇后问题求解
求解思路:对每行依次进行递归遍历。一行中的每个位置依次判断是否危险,如果不危险,则进行下一行位置的判定。如果危险,则进行下一列位置的判定。
最后,当判定完最后一行依旧合法时,则输出棋盘。
row:当前遍历的行索引;column:当前棋盘列数;chess:当前棋盘
*/
void EightQueen(int row,int column,int (*chess)[COLUMN])
{
    int i,j;
    int chess2[ROW][COLUMN]; //因为要递归遍历,所以,用一临时数组保存每次遍历时的棋盘。
    for(i=0;i<ROW;i++) //用chess初始化临时棋盘
    {
        for(j=0;j<COLUMN;j++)
        {
            chess2[i][j]=chess[i][j];
        }
    }
    if(ROW==row) //row从0开始,当==ROW时,表示已遍历完整个棋盘,且每个位置都符合条件。
    {
        printf("count:%d\n",++count); //开始输出棋盘
        for(i=0;i<ROW;i++)
        {
            for(j=0;j<COLUMN;j++)
            {
                printf("%d ",chess2[i][j]);
            }
            printf("\n");
        }
        printf("\n");
    }
    else 
    {
        for(i=0;i<COLUMN;i++)  //对一行中的每个位置进行判定
        {
            if(notDanger(row,i,chess2)) //判断该位置是否危险
            {

                for(j=0;j<COLUMN;j++) //判定该位置不危险后,需要先将该行初始为0.因为该行可能含有被上次递归遍历修改的值。
                {
                    chess2[row][j]=0;
                }

                chess2[row][i]=1; //该位置放置皇后
                EightQueen(row+1,column,chess2); //进行下一行皇后位置的判定
            }
        }
    }
}

/*
判定给出的位置是否危险
row:当前位置的行索引;column:当前位置的列索引;chess:当前棋盘
int:危险返回0,不危险返回1.
*/
int notDanger(int row,int column,int chess[][COLUMN]) //注意:二维数组声明时,第二个参数不可省略
{
    int i,j;
    //column 列的方向上是否危险
    for(i=0;i<ROW;i++)
    {
        if(1==chess[i][column])
        return 0;
    }
    //top left 左斜线方向上是否危险
    for(i=row,j=column;i>=0 && j>=0;i--,j--)
    {
        if(1==chess[i][j])
        return 0;
    }
    //top right 右斜线方向上是否危险
    for(i=row,j=column;i>=0 && j<COLUMN;i--,j++)
    {
        if(1==chess[i][j])
        return 0;
    }
    return 1;
}




你可能感兴趣的:(递归,八皇后)