藍橋杯-四階幻方(DFS)


標題:四階幻方

把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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM