BUPT-DSA 2019 Fall Chap.3 八皇后問題

八皇后可以擴充到n皇后,注意DEGREE不要開的太大,因爲解的數量增長非常快,八皇后才92,九皇后就有392組解了。
同樣使用dfs。

#include <cstdio>
#include <cmath>
#define DEGREE 8//八皇后,可以改成其他階數的

//數組使用自然下標[1,n],0號位空出
int result[DEGREE+1];//第i行的第result[i]列放一個皇后
bool book[DEGREE+1];//標記第i列是否放過皇后
int degree;//從外部讀入階數
int solution_cnt;//解計數器

bool isAvailable(int i,int step);//檢查第step行放i列是否可行
void printSheet();//打印棋盤

void dfs(int step)
{
	if(step==degree+1)//已經完成了n皇后,到達了第n+1步,可以打印了
	{
		printf("Solution #%d\n",solution_cnt++ );
		for(int i=1;i<=degree;++i)
			printf("%d%c",result[i],i==degree?'\n':' ' );
		printSheet();
		putchar('\n');
		return ;
	}
	for(int i=1;i<=degree;++i)//嘗試每一個位置
	{
		if(book[i]) continue;//標記用過就不用再檢測了
		//假設第step位選擇i
		if(isAvailable(i,step))//檢測第step個皇后放i是否可行
			{
				result[step]=i;//第step行放在第i列
				book[i]=1;//i標記使用
				dfs(step+1);//繼續搜索
				book[i]=0;
			}
	}
}

bool isAvailable(int i,int step)
{
	for(int j=1;j<step;++j)
	{
		if(result[j]==i)
			return false;//同一列肯定是不行的
		if(abs(step-j)==abs(i-result[j]))
			return false;//同一對角線也不行
	}
	return true;
}

void printSheet()
{
	bool sheet[degree+1][degree+1]={false};
	for(int i=1;i<=degree;++i)
		sheet[i][result[i]]=true;
	for(int i=1;i<=degree;++i)
		for(int j=1;j<=degree;++j)
			printf("%c%c",sheet[i][j]?'*':'.',j==degree?'\n':' ');
	putchar('\n');
}
int main(int argc, char const *argv[])
{
	degree=DEGREE;
	//scanf("%d",&degree);
	dfs(1);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章