標題:四階幻方 把1~16的數字填入4x4的方格中,使得行、列以及兩個對角線的和都相等,滿足這樣的特征時稱為:四階幻方。 四階幻方可能有很多方案。如果固定左上角為1,請計算一共有多少種方案。 比如: 1 2 15 16 12 14 3 5 13 7 10 4 8 11 6 9 以及: 1 12 13 8 2 14 7 11 15 3 10 6 16 5 4 9 就可以算為兩種不同的方案。 請提交左上角固定為1時的所有方案數字,不要填寫任何多余內容或說明文字。
記:
一開始直接用dfs搜索,發現時間太長,於是找規律
發現,幻方的值,為1累加到16的和除以階數4
(所以類似的n階幻方也可以這么做?)
另外一個3階的題目用同樣方法也行
http://www.cnblogs.com/mind000761/p/8595390.html
從而添加剪枝操作后,運行時間約1min
示例代碼:
1 #include <stdio.h> 2 #define MAX 16 /*可放置的最大數*/ 3 #define N 4 /*階數*/ 4 5 int key = 34; /*1到MAX的累加和除以MAX*/ 6 int count = 0; /*滿足條件的解*/ 7 int arr[N+1][N+1] = {0}; 8 int f[MAX+1] = {0}; 9 10 void dfs(int x) 11 { 12 int i,j,k,s; /*s用於剪枝操作*/ 13 14 if (x > MAX) 15 { 16 i = arr[1][1]+arr[2][2]+arr[3][3]+arr[4][4]; 17 j = arr[1][4]+arr[2][3]+arr[3][2]+arr[4][1]; 18 if (i != key || j != key) 19 { 20 return; 21 } 22 for (i = 1 ; i <= N ; i ++) 23 { 24 s = 0; 25 for (j = 1 ; j <= N ; j ++) 26 { 27 s += arr[j][i]; 28 } 29 if (s != key) 30 { 31 return; 32 } 33 } 34 35 count ++; 36 return; 37 } 38 39 for (i = 2 ; i <= MAX ; i ++)/*遍歷2-MAX*/ 40 { 41 if (!f[i]) 42 { 43 for (j = 1 ; j <= N ; j ++) 44 { 45 s = 0; 46 for (k = 1 ; k <= N ; k ++) 47 { 48 if (!arr[j][k]) 49 { 50 f[i] = 1; 51 arr[j][k] = i; 52 break; 53 } 54 s += arr[j][k]; 55 } 56 if (f[i]) 57 { 58 break; 59 } 60 if (s != key) 61 { 62 return; 63 } 64 } 65 dfs(x+1); 66 arr[j][k] = 0; 67 f[i] = 0; 68 } 69 } 70 71 return ; 72 } 73 74 int main(void) 75 { 76 f[1] = 1; 77 arr[1][1] = 1; 78 dfs(2); 79 printf("%d",count);/*416*/ 80 return 0; 81 }