八皇后問題(回溯法)代碼

轉自http://blog.csdn.net/xie376450483/article/details/6159037


#include<iostream>
using namespace std;

#define N 8
//N代表皇后數
void queen()
{
	int Count=0;		 //計算總共的解的數量
	int column[N+1];     //column[m]=n表示第m行,第n行放置了皇后,這裏下表並從0開始
	int row[N+1];		 //row[m]=1表示第m行沒有皇后,=0表示有皇后
	int b[2*N+1];		 //b[m]=1表示第m條主對角線沒有皇后,
	int c[2*N+1];        //c[m]=1表示第m條次對角線沒有皇后,=0表示有皇后
	int numQueen=1;		 //計數已經放置的皇后數目,當numQueen=N時候則表示已經完成探測
	int good=1;			 //good=1表示沒有發生衝突,good=0表示發生衝突
	
	//初始化這些標記
	for(int j=0;j<N+1;++j)
	{
		row[j]=1;
	}
	for(int j=0;j<2*N+1;++j)
	{
		b[j]=c[j]=1;
	}
	column[1]=1;
	column[0]=0;          //初始化第一行第一列,第二行第二列放置皇后
	do
	{
		//沒有發生衝突,則繼續向下探測,增加皇后或者判斷當前是否是解
		if(good)
		{
			//當前皇后數是解,打印,繼續向下探測
			if(numQueen==N)
			{
				Count++;
				cout<<"找到解"<<endl;
				for(int j=1;j<N+1;++j)
				{
					cout<<j<<"列"<<column[j]<<"行"<<endl;
				}
				//最後一個棋子向下移動,移動到本列最後一個
				while(column[numQueen]==N)
				{
					numQueen--;			//皇后數減1,即列數減1,回溯
					//回溯後將該列以及該列最後一行狀態位修改
					//第numQueen列column[numQueen]行處狀態位置修改
					row[column[numQueen]]=1;
					b[numQueen+column[numQueen]]=1;
					c[N+numQueen-column[numQueen]]=1;
				}
				column[numQueen]++;		//回溯至上一行,向上一行的下一列繼續探測
			}
			//當前不是解,那麼繼續向下探測
			else
			{
				//改變該位置對應標誌
				row[column[numQueen]]=0;
				b[numQueen+column[numQueen]]=0;
				c[N+numQueen-column[numQueen]]=0;
				//本次位置沒有發生衝突,也不是正確解,那麼就應該向下探測下一列的第一行
				column[++numQueen]=1;
			}
		}
		//如果當前發生了衝突,就在本列繼續向下,如果到了本列最後一行,則回溯到上一列
		else
		{
			while(column[numQueen]==N) //到了本列最後一行,還是衝突,那麼回溯到上一列
			{
				numQueen--;
				row[column[numQueen]]=1;
				b[numQueen+column[numQueen]]=1;
				c[N+numQueen-column[numQueen]]=1;
			}
			column[numQueen]++;	//發生衝突了,又沒有到本列的最後一行,那麼在本列繼續向下一行探測
		}
		//檢測放置了這個位置後是否衝突
		good=row[column[numQueen]]&b[numQueen+column[numQueen]]&c[N+numQueen-column[numQueen]];
	}while(numQueen);
	cout<<N<<"皇后總共找到解:"<<Count<<"個"<<endl;
}
void main()
{
	queen();
	system("pause");
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章