1. 程式人生 > >codevs1295 N皇后問題 解題報告

codevs1295 N皇后問題 解題報告

N皇后問題  codevs1295黃金Gold 【問題描述】 在N*N的棋盤上放置N個皇后(n<=10)而彼此不受攻擊(即在棋盤的任一行,任一列和任一對角線上不能放置2個皇后),程式設計求解所有的擺放方法。
【輸入格式】     輸入:n 【輸出格式】 每行輸出一種方案,每種方案順序輸出皇后所在的列號,各個數之間有空格隔開。若無方案,則輸出no solute! 【輸入樣例】     4 【輸出樣例】 2  4  1  3 3  1  4  2
【解題思路】 依然依然是搜尋回溯的經典題。因為皇后可以控制它所在的兩條對角線,我們發現,棋盤上的對角線都滿足這樣的特點:要麼橫縱座標之和相等,要麼橫縱座標之差相等。所以可以用兩個判斷陣列標記兩種對角線有沒有被皇后控制。。搜尋是逐行搜尋,每行只有一個皇后,所以不用擔心每行的皇后互相沖突,只需要再開一個判斷陣列標記每一列有沒有被皇后控制即可。
a[i]表示橫縱座標之和為i的對角線是否有被皇后控制。。 b[i+n]表示橫縱座標之差為i的對角線是否有被皇后控制。。。因為c++無法處理負陣列,所以給每一個i都加上n,就不會出現負數的情況了。。 c[i]表示第i列有沒有被皇后控制。。 【程式碼】
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int a[100],b[100],c[100],d[100],n;
bool pd;

void print()
{
	int i;
	for (i=1;i<=n;++i)
	  printf("%5d",d[i]);
	printf("\n");
	pd=true;
	return;
}

void dfs(int dep)
{
	int r;
	if (dep==n+1) print();
	for (r=1;r<=n;r++)//逐行搜尋,按列迴圈,dep是行數,r是列數
	  if (!a[dep+r]&&!b[dep-r+n]&&!c[r])//精髓所在!!!!!(重要的事情打五個!)
	  {
	  	d[dep]=r;//d是記錄陣列
	  	a[dep+r]=1;
	  	b[dep-r+n]=1;
	  	c[r]=1;
	  	dfs(dep+1);
	  	a[dep+r]=0;//回溯一步
	  	b[dep-r+n]=0;
	  	c[r]=0;
	  }
	return;
}

int main()
{
	scanf("%d",&n);
	pd=false;
	dfs(1);
	if (pd==false)
	  printf("no solute!");
	return 0;
}