八皇后問題 二維、一維、回溯

在 8×8 的國際象棋棋盤上放置八個皇后,使得任何一個皇后都無法直接吃掉其他的皇后?

爲了達到此目的,任兩個皇后都不能處於同一條橫行、縱行或斜線上。

下面代碼是輸出所有可能的皇后排列方法 共92種

//八皇后問題 
#include<iostream>
using namespace std;
int c[8],q[8][8];//q[8][8]是用來記錄皇后的位置的 c[8]是用來記錄着一列有沒有皇后 
void dfs(int count);
bool judge(int row,int col);//用來判斷斜線上有沒有皇后 
int cnt=0;//記錄多少种放法 
int main()
{
	dfs(0);
	cout<<cnt;
	return 0;
}
void dfs(int count)//尋找第count行 皇后的位置 
{
	int i,j,k;
	if(count==8){//當八個皇后都排好時 輸出 
		cnt++;
		for(i=0;i<8;i++){
			for(j=0;j<8;j++){
				if(q[i][j]==1){
					cout<<'#';//皇后的位置輸出'#' 
				}
				else{
					cout<<'0';
				}
			}
			cout<<'\n';
		}
		cout<<"--------------------\n";
		return ;
	}
	for(i=0;i<8;i++){
		if(c[i]==0){//當這一列沒有皇后時 再進入判斷 
			if(judge(count,i)){//當斜線方向也沒有皇后時 
				q[count][i] = 1;//記錄位置 
				c[i] = 1;
				dfs(count+1);//進入下一行 
				q[count][i]=0;//如果從dfs(count+1)出來後要對第count行的第i+1列進行判斷 所以 c[i] = 0;q[count][i]=0;
				c[i] = 0;
			}
		}
	}
}
 
bool judge(int row,int col)
{
	int i=1,j,k;
	if(c[col]){
		return false;
	}
	while((--row)>=0){
		//row--;
		if(col+i<8){
			if(q[row][col+i]){
				return false;
			}
		}
		if(col-i>=0){
			if(q[row][col-i]){
				return false;
			}
		}
		i++;
	}
	return true;
}

//用一維數組表示 c[i] = j 第i行的第j個元素是皇后  
#include<iostream>
using namespace std;
int c[9],cnt=0; 
void dfs(int count);
bool judge(int row,int col);
int main(){
	dfs(1);
	cout<<cnt;
	return 0;
}
void dfs(int count)
{
	int i,j,k;
	if(count==9){
		for(i=1;i<=8;i++){
			for(j=1;j<=8;j++){
				if(c[i]==j){
					cout<<"$";
				}
				else{
					cout<<"0";
				}
			}
			cout<<endl;
		}
		cout<<endl;
		cnt++;
	}
	for(i=1;i<=8;i++){//捨棄第一個 讓零作爲一個標誌位 
		if(judge(count,i)){
			c[count] = i;
			dfs(count+1);
			c[count] = 0;
		}
	}
}
bool judge(int row,int col)
{
	int i,j,k;
	for(i=1;i<row;i++){//檢查同一列 
		if(c[i]==col){
			return false;
		}
	}
	for(i=1;i<row;i++){//檢查兩個斜線方向 
		if(c[row-i] == col-i || c[row-i]==col+i){
			return false;
		}
	} 
	return true;
}

//用回溯寫
#include<iostream>
using namespace std;
int c[9],cnt=0;
bool judge(int row,int col);
void print();
int main()
{
	int i,j,k;
	k = 1;
	c[k] = 0;
	while(k>0){
		c[k] += 1;
		while(c[k]<=8 && !judge(k,c[k])){//如果這一列不符合條件 就看下一列 
			c[k]+=1;
		}
		if(c[k]<=8){//如果這一行中有皇后 
			if(k==8){//如果到了第八行 說明全部完成  
				print();
				cnt++;
				c[k] = 0;
				k--; //回溯到上一行並且這一行的皇后復位爲0
			}
			else{
				k++;//看下一行 
				c[k] = 0;
			}
		}
		else{//未找到 則回溯到上一行 
			c[k] = 0;//復位爲0 
			k--;//回溯到上一行 
		}
	}
	cout<<cnt;
	return 0;	
} 
bool judge(int row,int col)
{
	int i,j,k;
	for(i=1;i<row;i++){
		if(c[i]==col){
			return false;
		}
	}
	for(i=1;i<row;i++){
		if(c[row-i] == col-i || c[row-i]==col+i){
			return false;
		}
	} 
	return true;
}
void print()
{
	for(int i=1;i<=8;i++){
		for(int j=1;j<=8;j++){
			if(c[i]==j){
				cout<<"$";
			}
			else{
				cout<<"0";
			}
		}
		cout<<endl;
	}
	cout<<endl;
}


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