N皇后问题 dfs+栈

  1. 定义了一个结构体Stack,包含两个数组x和y,分别用来存储每一行皇后的列的位置,size表示当前已经放置的皇后的数量,front表示当前栈顶的位置。

  2. 定义了创建栈的函数creats,如果栈为空,则创建一个新栈,并初始化其大小和栈顶位置。

  3. 定义了入栈操作push,将新的皇后的位置放入栈中,并更新栈的大小和栈顶位置。

  4. 定义了出栈操作pop,将栈顶的皇后移除,并更新栈的大小和栈顶位置。

  5. 定义了判断函数panduan,检查当前栈中的皇后是否满足任意两个皇后不在同一行、同一列或同一对角线上的条件。

  6. 定义了打印函数print,打印出所有满足条件的皇后的位置。

  7. 定义了深度优先搜索函数dfs,通过递归的方式尝试所有可能的皇后位置组合,当找到一个满足条件的组合时,就将其打印出来,并更新计数器的值。

  8. 在主函数中,首先读取用户输入的n值,然后创建一个空栈,调用dfs函数进行搜索,最后输出找到的解的数量。如果没有找到解,就输出"no solute!"。

#include<bits/stdc++.h>

using namespace std;

typedef struct{

  int x[10];//行坐标

  int y[10];//列坐标

  int size;//栈长度

  int front;//栈顶

}*stacks,Stack;

void creats(stacks &p)//创建栈

{

  if(p==NULL)

  {

    p=new Stack;

    p->size=0;

    p->front=0;

  }

}

void push(stacks &p,int x,int y)//入栈

{

  if(p->size==0)

  {

    p->x[0]=x;

    p->y[0]=y;

    p->front=0;

  }

  else{

    p->front++;

    p->x[p->front]=x;

    p->y[p->front]=y;

  }

  p->size++;

}

void pop(stacks &p)//弹栈

{

  p->size--;

  p->front--;

}

int panduan(stacks &p)//判断栈顶坐标是否合法

{

  int x0=p->x[p->front];

  int y0=p->y[p->front];

  for(int i=0;i<p->size-1;i++)

  {

    int x1=p->x[i];

    int y1=p->y[i];

    if(x1==x0||y1==y0)

      return 0;

    if(abs(x1-x0)==abs(y1-y0))

      return 0;

  }

  return 1;

}

void print(stacks &p)//输出符合元素坐标,即遍历栈输出

{

  for(int i=0;i<p->size;i++)

  {

    cout<<p->y[i]<<" ";

  }

  cout<<endl;

}

int dfs(int n,int h,stacks &p,int &count)//深搜  count代表符合题意的数据个数

{

  if(h>n)

    return 0;

  for(int i=1;i<=n;i++)

  {

    push(p,h,i);//遇到坐标先入栈

    if(panduan(p)&&n==h)//判断栈顶元素是否合法 若此时的行数为最后一行 即这组数据符合题意

    {

      print(p);//输出这组数据

      count++;

      pop(p);   //弹栈 继续循环

    }

    else if(panduan(p))//若不为最后一行 (但是该店符合题意)那就进行下一行的深搜

    {

      dfs(n,h+1,p,count);//深搜

      pop(p);//搜索完要进行弹栈 以便改行下一个元素入栈

    }

    else{

      pop(p);//若不符合题意 弹栈 继续循环

      continue;

    }

  }

  return count;返回符合题意的数据个数

}

int main()

{

  int n;

  cin>>n;

  stacks p=NULL;

  creats(p);

  int c = 0;

  dfs(n,1,p,c);

  if(c==0)//若数据为0

    cout<<"no solute!";//无数据

  return 0;

}

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值