#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
template<class T>
class Queen
{
public:
void Input(void); //输入棋子个数
void Output(vector<T> &vec,int &i); //输出成功的棋盘状态数
void Trial(int &i); //进行布局函数
private:
T chess; //棋子个数存放在容器中
vector<T> vec; //存放每行合格棋子的位置
};//Queen
template<class T>
void Queen<T>::Input(void)
{
T a;
cin>>a; //输入棋子个数,即棋盘大小
chess=a;
}//Input
template<class T>
void Queen<T>::Output(vector<T> &vec,int &i)
{
if(vec.size()==chess)
{
cout<<endl;
vector<T>::iterator it=vec.begin();
while(it!=vec.end())
{
switch(*it)
{
case 1:
cout<<"O * * *"<<endl;break;
case 2:
cout<<"* O * *"<<endl;break;
case 3:
cout<<"* * O *"<<endl;break;
case 4:
cout<<"* * * O"<<endl;break;
}//switch
it++;
}//while
}//if
cout<<endl;cout<<endl;
if(vec.size()>0)
{vec.pop_back();i--;}//进入Output函数时i=5,故i-1,返回当前行,便于其他列遍历
}//Output
template<class T>
void Queen<T>::Trial(int &i)
{
if(i>chess)
Output(vec,i);
else //在第i行第j列放置一个棋子
{
for(int j=1;j<=chess;j++)
{
//------------取棋子--------------
if(i==1)//第一行棋子位置都合法,所以取
{ vec.push_back(j); i++;
Trial(i);}//if
else
{
vector<T>::iterator it=vec.begin();
int k=1;//k记录vec中被比较元素的行数
while(it!=vec.end()) //将第i行第j列的棋子与前i-1行进行比较,看是否布局合法
{
if((abs(*it-j)!=0)&&(abs(*it-j)!=(i-k)))//列相减不等0表示同一行,不等于(i-k)表示不再斜对角线上
{it++; k++;}//if
else //与某一行比较后不符合要求,说明该行第j列的位置不合法,无需进行后续比较
break;
}//while
if(it==vec.end()) //前i-1行都比较完,说明布局合法
{ vec.push_back(j); i++;
Trial(i);}//if//将该行合理布局的j值存入容器中,进行下一行布局实验
//-----------舍棋子---------------
else //前i-1行未比较完,说明该行j列位置不合法,舍弃该位置
;
}//else
if((j==4)&&(vec.size()<i))//当j=4时而容器中棋子个数小于行数,说明该行不存在布局合理的位置
if(vec.size()>0)
{vec.pop_back(); i--; break;}//删除上一行棋子的布局,改走其他路径
}//for
}//else
}//Trial
void main()
{
int start=1;
Queen<int> Q;
Q.Input();
Q.Trial(start);
}//main
回溯法——四皇后问题
原文作者:回溯法
原文地址: https://blog.csdn.net/u014033518/article/details/39012263
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/u014033518/article/details/39012263
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。