算法入门经典-第七章 例题7-2 八皇后问题

Posted Tina

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法入门经典-第七章 例题7-2 八皇后问题相关的知识,希望对你有一定的参考价值。

原本利用回溯思想解决的经典八皇后问题,其实也是可以用递归解决的~

八皇后的递归解决思路:

从第一行开始,依次判断0~8列的哪一列可以放置Queen,这样就确定了该行的Queen的位置,然后行数递增,继而递归实现下一行的判断,依次类推直到行数增加到8(行数从0开始的),此时为递归-----归的条件,即表示一种八皇后的解决方法完成,打印结果;之后进行下一种解决方法的寻找,大致思路个人理解是这样

noDanger(row,j,(*chess)[8])函数是判断第row行第j列是否可以放置Queen

 

 

#include<stdio.h>
int count=0;
//参数row:起始行
//参数n:表示列数
//参数(*chess)[8]表示指向棋盘每一行的指针 
int NotDanger(int row,int j,int (*chess)[8])//比较不同行同列上是否有其他皇后 
{
    int i,k,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; 
     
} /*
int noDanger(int row,int j,int (*chess)[8])  
{  
    int flag1=0,flag2=0,flag3=0,flag4=0,flag5=0;  
    int i,k;  
    //判断列  
    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<8&&k>=0;k--,i++)  
    {  
        if(*(*(chess+i)+k)!=0)  
        {  
            flag4=1;  
            break;  
        }  
    }  
    //判断右上方  
    for(i=row,k=j;i>=0&&k<8;k++,i--)  
    {  
        if(*(*(chess+i)+k)!=0)  
        {  
            flag5=1;  
            break;  
        }  
    }  
    if(flag1||flag2||flag3||flag4||flag5)  
    {  
        return 0;  
    }else  
    {  
        return 1;  
    }  
}  */
EightQueen(int row,int n,int (*chess)[8])
{
    int chess2[8][8];
    int i,j;
    for(i=0;i<8;i++)
    {
        for(j=0;j<8;j++)
        {
            chess2[i][j]=chess[i][j];
            
        }
    }
    if(8==row)
    {
        printf("第%d 种\n",count+1);
        for(i=0;i<8;i++)
        {
            for(j=0;j<8;j++)
            printf("%3d ",*(*(chess2+i)+j));
             printf("\n"); 
        }  
        
        count++;  
    }
    else{
        //判断这个位置是否危险 j<列 
        for(j=0;j<n;j++)
        {
            if(NotDanger(row,j,chess2))//尝试每一列是否危险
            {
                
                for(i=0;i<8;i++)
                {
                    //整行所有列的位置赋值为0 
                    *(*(chess2+row)+i)= 0;
                } 
                *(*(chess2+row)+j)=1;//皇后的位置赋值为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; 
     }
     EightQueen(0,8,chess);
     printf("总共有%d种解决方法",count);
     return 0;
 }

 

以上是关于算法入门经典-第七章 例题7-2 八皇后问题的主要内容,如果未能解决你的问题,请参考以下文章

算法入门经典-第七章 例题7-2-2 可重集的排列

算法入门经典7.4回溯法八皇后问题

算法入门经典-第七章 例题7-1 除法

算法-编程的灵魂--八皇后

生活日用算法——八皇后问题

八皇后问题