8皇后回溯法

来源:互联网 发布:淘宝买家怎么改差评 编辑:程序博客网 时间:2024/06/06 03:12

问题描述:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上问有多少种摆法。8皇后是典实际上一个类似枚举的搜索尝试过程,它的的基本思想是在所有的解空间中,先深度搜索求出一种解法不满足约束条件的解时,回退到之前的解,继续对问题求解8皇后也可以推广为一般情形,将棋盘扩展为n*n,此时皇后个数n(n=1或>=4时有解)。

思路:逐行放置,逐列搜索。从当前行的第一列开始搜索,判断该位置是否合法。合法则递归判断下一行,不合法则搜索下一列,直到最后一列也不符合,或者在最后一行放下棋子就返回上一次递归,一直到第一行遍历完毕。


#include<iostream>  #include<cmath>  #include<windows.h>  #define MAXSIZE 8    char a[MAXSIZE][MAXSIZE];  int Totalnumber=0;    using namespace std;  bool isillegal(int row,int col)//判断该位置是否合法(逐行判断故只要判断列和对角线)  {      for(int i=0;i<row;i++)      {          if(a[i][col]=='*') return false;//判断是否在同一列          else continue;        }      for(int i=0;i<row;i++)//判断是否在同一对角线      {          for(int j=0;j<MAXSIZE;j++)          {              if(abs(i-row)==abs(j-col) && a[i][j]=='*') return false;//同一对角线的斜率相同              else continue;          }      }      return true;  }    void print()  {      for(int i=0;i<MAXSIZE;i++)      {          for(int j=0;j<MAXSIZE;j++)          {              cout<<a[i][j]<<' ';          }          cout << '\n';      }      cout << '\n';  }    void solution(int number)//参数为当前行数  {      for(int i=0;i<MAXSIZE;i++)      {          if(isillegal(number,i))          {              a[number][i]='*';              if(number==MAXSIZE-1)              {              Totalnumber++;//满足条件的总数               print();//输出数组              cout << Totalnumber<<'\n';              system("pause");//输出后暂停              }               else solution(number+1);              a[number][i]='#';          }            }  }    void inits()//初始化数组  {      for(int i=0;i<MAXSIZE;i++)      {          for(int j=0;j<MAXSIZE;j++)          {              a[i][j]='#';          }      }  }    int main()  {      inits();      solution(0);      return 0;  }  


这是最后的运行结果“*”表示棋子:




原创粉丝点击