八皇后的两种思路

题目描述:n皇后是指在一个n行n列的棋盘上,将n个皇后摆放在不同的位置,不能出现在同一行,同一列,同一斜线,问有多少种解法。

思路一:

建立一个二维数组,初始化都为0,(皇后的位置置1)从第一行开始放皇后,列有八种情况,从第一种情况开始,如果这个位置的上面的列,左上正对角线,以及右上正对角线没有皇后,则是安全的,这个位置可以放置皇后,继续递归下一行,否则继续探索这一行的其他列,如果这一行的所有列都不能放下皇后,则向上返回一层(从上一行的其他满足情况的列又开始向下探索)。 当有一种解法时打印棋盘,开始向上回溯探索当前列到n-1列是否有满足情况的,如果有则继续向下递归没有则向上一行回溯 直到回溯到第0行的第n-1列然后向下递归,没有向上的回溯时才完毕

思路二:

n个皇后分别在不同行的不同列,可以先将1–n进行排列组合,每个数的每个位置代表对应行的列,将所有的排列组合去除掉在同一斜线上的情况,剩下的就是n皇后的题解

代码1:

#include<string.h>
#include <iostream>
#include <cmath>
using namespace std;
int _count=1;
int judge_safe(int check[8][8],int row,int m,int n)
{
    //判断当前位置的的前面数组里有没有和当前位置在同一条直线上
    //分成四部分,左上角,左下角,右上角和右下角

    //列
    for(int i=0;i<m;i++)
    {
        if(check[i][n]==1)
          return 1;
    }
    //左上角
    for(int i=m-1,j=n-1;i>=0&&j>=0;i--,j--)
    {
        if(check[i][j]==1)
            return 1;
    }
    //右上角
    for(int i=m-1,j=n+1;i>=0&&j<row;i--,j++)
    {
        if(check[i][j]==1)
            return 1;
    }
    return 0;
}


 void eight_queens(int check[8][8],int row,int m)//m表示当前行
 {

     if(m==8)
     {
         cout<<"-----------第--"<<_count<<"-----种-----------------"<<endl;
         //已经全部找到了一组满足情况的棋盘
         for(int i=0;i<row;i++)
         {
             for(int j=0;j<row;j++)
             {
                 cout<<check[i][j]<<" ";
             }
             cout<<endl;
         }
         _count++;
     }

     //先从第一行开始放皇后,从0~7列一个一个试,如果所下的地方与之前下的地方不冲突,
     //则当前位置是安全的,并将这个位置置1


         for(int j=0;j<row;j++)
         {
             if( judge_safe(check,row,m,j)==0)//调用judge_safe函数来判断所下的位置是否安全
             {                             //如果j这一列都会与上面的冲突,则回溯到上一行,并从上一行的j+1的地方又开始判断

                 //为避免不能一次性下对地方,所以现将这一行的元素都置0,
                 //再将check[row][j]置1,否则一行可能会出现多个1

                check[m][j]=1;
                 //第row行已经下好继续第row+1
                 eight_queens(check,row,m+1);

                 check[m][j]=0;//如果不满足情况,则恢复之前的状态
             }
         }
 }


int main()
{
    //定义并初始化一个8*8的棋盘
    //棋盘刚开始的元素都为0,将皇后的位置置为1.
    int check[8][8]={0};

    eight_queens(check,8,0);

    return 0;

}

在这里插入图片描述
代码2:

#include<string.h>
#include <iostream>
#include <cmath>
using namespace std;
int count=1;
void _swap(int a,int b,int *arr)
{
    int temp=arr[a];
    arr[a]=arr[b];
    arr[b]=temp;
}
 void is_ok(int check[9],int N)
  {
      //如果在同一条斜线上则返回0,从一个数开始判断它后面的元素是否和他在一条线上
      // 如果 j-i=abs(check[i]-check[j]);则在同一条线上
      for(int i=1;i<=N-1;i++)
      {
          for(int j=i+1;j<=N;j++)
          {
              if(j-i==abs(check[i]-check[j]))
            //  if(j-i==check[i]-check[j]||j-i==check[j]-check[i])
               return ;
          }
      }
     cout<<"---第--"<<count<<"--种---"<<endl;
     for(int i=1;i<=N;i++)
        cout<<i<<" "<<check[i]<<endl;
        ++count;
  }

//N为8,k代表待排列的位置
 void  eight_queens(int check[9],int N,int k)
 {
     if(k==9)
     {
        is_ok(check,N);
     }
     for(int i=k;i<=N;i++)
     {
         _swap(i,k,check);
         eight_queens(check,N,k+1);
         _swap(i,k,check);//回溯到原来的状态
     }
 }
 int main()
{
    //八皇后,每一列只存放一个位置,可以先将八个数进行全排列,
    //将所有的排列组合中去掉在同一条斜线上的组合,剩下的就是八皇后的解
   int check[9]={0,1,2,3,4,5,6,7,8};
    eight_queens(check,8,1);
    return 0;
}

在这里插入图片描述

发布了24 篇原创文章 · 获赞 4 · 访问量 2618

猜你喜欢

转载自blog.csdn.net/weixin_41548145/article/details/104348743
今日推荐