codevs1295 N皇后問題 解題報告
阿新 • • 發佈:2019-02-10
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列有沒有被皇后控制。。
【程式碼】
【輸入格式】 輸入:n 【輸出格式】 每行輸出一種方案,每種方案順序輸出皇后所在的列號,各個數之間有空格隔開。若無方案,則輸出no solute! 【輸入樣例】 4 【輸出樣例】 2 4 1 3 3 1 4 2
【解題思路】 依然依然是搜尋回溯的經典題。因為皇后可以控制它所在的兩條對角線,我們發現,棋盤上的對角線都滿足這樣的特點:要麼橫縱座標之和相等,要麼橫縱座標之差相等。所以可以用兩個判斷陣列標記兩種對角線有沒有被皇后控制。。搜尋是逐行搜尋,每行只有一個皇后,所以不用擔心每行的皇后互相沖突,只需要再開一個判斷陣列標記每一列有沒有被皇后控制即可。
#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; }