回溯法——四皇后问题

#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


回溯法——四皇后问题_第1张图片

你可能感兴趣的:(回溯法,四皇后)