关于回溯和后宫
這是八皇后問題的升級版,主要是一個荒淫無道的國王娶的一堆皇后瓜分天下的故事。不清楚的同學請轉身百度,這里小子就不多說了。
回溯是我們玩迷宮游戲專用的一種思維模式。主要是先沿著一個方向走,若干步后若無法繼續走下一步,則退回一步,朝另一個方向探索,直到終點或返回起點。所以我們可以先從第一行左邊開始,一個一個的往下一行放置皇后,每放置一個皇后,判斷一次是否與之前所放置的皇后的領域有所沖突。
判斷項有三項,分別是列、主對角線、副對角線。若是領域已被占領,則判偽;若未被占領,則判真。判真的情況下,該點即可作為其中一個可能的答案。讓我們來看一下如何去判斷領域是否沖突:
1.列的領域比較好判斷,就是一個數組,角標和已放置的皇后的橫坐標相同的,即標記為1,表示已有皇后將此列占領,未占領的即標記為0。
2.主對角線較為復雜,我們先看下邊的圖:
不難得出,同一主對角線的橫縱坐標的差是相同的,那么就將差值當做判斷數組的角標,用1、0分別標記已占領和未占領,不過有些坐標的差值會是負值,但數組的角標不會是負值,所以為了防止這種情況,要為差值同一加上一個數,以保證結果是正值。
3.副對角線的判斷方法也可從上圖推出,這里就交給同學們去思考了。
以上就是該題的思考過程,代碼如下:
1 #include<stdio.h> 2 int n;//有n個皇后 3 int sum=0;//方法總數 4 int flag2[101]={0};//A對角線標 5 int flag3[101]={0};//B對角線標 6 int ans[9]={0};//放置坐標,角標為x,數據為y 7 int flag1[9]={0};//列標 8 void out();//該函數主要用于方法數統計與輸出結果 9 void search(int k);//用于回溯,從第k行開始放置 10 int main() 11 { 12 scanf("%d",&n); 13 search(1);//從第1行開始 14 return 0; 15 } 16 void search(int k) 17 { 18 int i; 19 for(i=1;i<=n;i++) 20 { 21 if( (!flag1[i]) && (flag2[i-k+10]==0) && (flag3[i+k]==0) ) 22 /*判斷語句第一節判斷這一列是否在之前皇后的領域中, 23 第二節判斷主對角線,第三節判斷副對角線*/ 24 { 25 ans[k]=i; 26 flag1[i]=1; 27 flag2[i-k+10]=1; 28 flag3[i+k]=1; 29 if(k==n) out();//若到邊界即達成一種情況 30 else search(k+1);//未到邊界則繼續探索 31 flag1[i]=0; 32 flag2[i-k+10]=0; 33 flag3[i+k]=0; 34 } 35 } 36 } 37 void out() 38 { 39 int i; 40 sum++; 41 printf("%d:\n",sum); 42 for(i=1;i<=n;i++) 43 printf("(%d,%d)\n",i,ans[i]); 44 }? 代碼如有錯誤,歡迎指出,如果這篇博客給了讀者幫助,那是小子的榮幸。
轉載于:https://www.cnblogs.com/LegendLa/p/4515039.html
總結
- 上一篇: 一个类怎样引用另外一个类的成员变量或方法
- 下一篇: 07、poly-A内参和杂交内参(arr