C++算法之八皇后问题--(3)

什么是八皇后问题呢?

       在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。八皇后问题是一个比较经典的算法问题,实际上它主要体现了回溯法的应用。

      首先 不懂国际象棋走法的朋友,这里先普及一下国际象棋的规则,国际象棋在一个8*8格子的棋盘上进行,皇后是国际象棋中威力最大的棋子(估计是因为欧洲很多女皇的原因吧),等同于中国象棋中的车,不过,皇后比车还要厉害 因为她还可以斜着走,下图就是一种解法,如图1所示:

     《C++算法之八皇后问题--(3)》

问题解决思路:

        选一个方向往前走,能进则进,不能进则退并尝试另外的路径。首先我们来分析一下国际象棋的规则,这些规则能够限制我们的前进,也就是我们前进途中的障碍物。一个皇后q(x,y)能被满足以下条件的皇后q(row,col)吃掉。x=row(纵向不能有两个皇后), y=col(横向不能有两个皇后),col + row = y+x;(斜向正方向),col – row = y-x;(斜向反方向)。遇到上述问题之一的时候,说明我们已经遇到了障碍,不能继续向前了。我们需要退回来,尝试其他路径。

       我们将棋盘看作是一个8*8的数组,这样可以使用一种蛮干的思路去解决这个问题,这样我们就是在8*8=64个格子中取出8个的组合,C(64,8) = 4426165368,显然这个数非常大,在蛮干的基础上我们可以增加回溯,从第0列开始,我们逐列进行,从第0行到第7行找到一个不受任何已经现有皇后攻击的位置。 第五列的时候,摆放任何行都会受到上图所示已经存在的皇后的攻击,这时候我们认为我们撞了南墙了,是回头的时候了,我们后退一列,将原来摆放在第四列的皇后。(3,4)拿走,从(3,4)这个位置开始,我们在第四列中寻找下一个安全位置为(7,4),再继续到第五列,发现第五列仍然没有安全位置,回溯到第四列,此时第四列也是一个死胡同了,我们再回溯到第三列,这样前进几步,回退一步,最终直到在第8列上找到一个安全位置或者第一列已经是死胡同,但是第8列仍然没有找到安全位置为止。

       代码如下:

using namespace std;

class CQueen
{
    int aQueen[8];
    int sum;
 int xx;
 int yy;
public:
    CQueen();
    int judge(int x,int y);
    void show(int ix,int iy);
    void step(int ix,int iy);
};

CQueen::CQueen()
{
 xx = 1;
 yy = 1;
    sum=0;
    for(int i=0;i<8;i++)
        aQueen[i]=0;
}

int CQueen::judge(int x,int y)
{
    for(int i=0;i        if(aQueen[i]==y || aQueen[i]+x-i==y || aQueen[i]-x+i==y) 
   return 0;
 return 1;
}

void CQueen::step(int ix,int iy)
{
    int x=0,y=0;
 x= ix;
 y = iy;
    while(aQueen[0]<8)
    {
        while(y<8)
        {    
            if(judge(x,y))
            {
                aQueen[x] = y;
                x++;
                y = 0;
            }
            else 
    y++;
            if(y == 8 && x != 8)
                if(aQueen[--x] != 7) 
     y = ++aQueen[x];
                else if(aQueen[0]!=7)
                    y = ++aQueen[--x];
                else
                    aQueen[0]=8;
        }
        if(x==8)
        {
   if (1)
   {
    show(ix,iy);
    if(aQueen[--x] != 7) 
     y = ++aQueen[x];
    else 
     y = ++aQueen[--x];

   }
   else
   {

   }

        }
    }
}//算法

void CQueen::show(int ix,int iy)
{
 int show = 0;
 for(int k=0;k<8;k++)
 {
  if ((iy ==k +1) && (ix == aQueen[k]+1))
  {
   show = 1;
  }
 }
 if (show)
 {
    //可以显示棋盘
    cout<<"\t---------------------------------\n";
    for(int i=0;i<8;i++)
    {
        cout<<"\t| ";    
        for(int j=0;j            cout<<"  | ";
        cout<<"* | ";
        for(j++;j<8;j++)
            cout<<"  | ";
        cout<<"\n\t---------------------------------\n";
    }

    cout<<"坐标为:\t";
    for(int k=0;k<8;k++)
        cout<<'('<    cout<<'\t'<< ++sum < }
}
void main()
{
    CQueen a;

 int x,y;
 cin >>x;
 cin >>y;
 a.step(x,y);
} 

      


    原文作者:八皇后问题
    原文地址: https://blog.csdn.net/fanyun_01/article/details/79433872
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注