1. 程式人生 > 遊戲 >Steam新調查結果顯示日區使用者猛增 愛玩PC遊戲了

Steam新調查結果顯示日區使用者猛增 愛玩PC遊戲了

n皇后問題:
* 給定一個n*n的棋盤,向該棋盤中放入n個皇后,使得n個皇后之間不在同行同列或同斜線,問有多少種方法
*
* 解題思路:
* 採用深度優先搜尋的思想:
* 1.整體上通過按行的思想,從第0行到第n-1行逐層深入進行遞迴。
* 2.每次遞迴時要記錄之前所有已經放好的皇后的位置,用於接下來判斷該行哪些位置能放皇后

 

1.未優化常數的方法

程式碼及解析:

 1 public static int num1(int n) {
 2         if (n < 1) {
 3             return 0;
 4         }
 5         int
[] record = new int[n];//開闢用於記錄0--n-1行皇后所在列位置的陣列空間 6 return process1(0,record,n); 7 } 8 9 /* 10 * i表示目前深度優先搜尋所尋找到的層數 11 * []record記錄了0——i-1層的皇后所在的列數位置 12 * n表示一共要探索的總層數 13 * 返回值:返回可以進行的擺放方式 14 */ 15 public static int process1(int i,int[] record,int n) {
16 if (i == n) {//說明0——n-1層的皇后位置都被正常放好,可以返回一種有效的擺放方式 17 return 1; 18 } 19 int ans = 0; 20 for (int k = 0; k < n; k++) { 21 if (isValid(record,i,k)) {//如果在當前i-1層擺放的情況下,第i層第k列允許放一個皇后 22 record[i] = k; 23 ans += process1(i+1,record,n);
24 } 25 } 26 return ans; 27 } 28 29 //判斷當前位置能否放入皇后 30 public static boolean isValid(int[] record,int i,int k) { 31 for (int j = 0; j < i; j++) { 32 if (record[j] == k || Math.abs(i - j) == Math.abs(record[j] - k)) { 33 return false; 34 } 35 } 36 return true; 37 }

 

2.優化方法:

優化思路:
* 使用數值中的每一位的0/1來表示皇后位置,第i位為1/0表示第i列有/無皇后
* 所以如果該列有了一個皇后,後續的皇后都不能在這一列。
* 而不能同斜線問題,則用位運算的左移和右移來進行實現

程式碼及解析:

 1 //因為int最大值為2^32 - 1,所以我們討論不超過32皇后的問題
 2     public static int num2(int n) {
 3         if (n < 1 || n > 32) {
 4             return 0;
 5         }
 6         int limit = 1 << n;//n個皇后只要用n位即可,但int數一共有32位,所以加一個限制條件,讓它只用n位
 7         return process2(limit,0,0,0);
 8     }
 9     
10     /*
11      * col用來處理皇后放置問題的列限制,1表示不能放皇后,0則可以
12      * left用來處理皇后放置問題的左斜線限制,1表示不能放皇后,0則可以
13      * right用來處理皇后放置問題的右斜線限制,1表示不能放皇后,0則可以
14      */
15     public static int process2(int limit,int col,int left,int right) {
16         if (col == limit) {//所有列都不能放則說明n個皇后已放滿,形成了一個有效的放置情況
17             return 1;
18         }
19         int pos = limit & (~(col | left | right));//得到能放皇后的位置(即所有為1的位置)
20         int ans = 0;
21         while (pos != 0) {
22             int rightOne = pos & (~pos + 1);//獲取最右位,從該位(列)開始進行深度搜索
23             pos = pos - rightOne;//因為該列有了皇后,所以對pos進行更新
24             ans += process2(limit,col | rightOne,left | rightOne << 1,right | rightOne >> 1);
25         }
26         return ans;
27     }