2016藍橋杯C++A組第六題 寒假作業【暴力搜索】


原題:

現在小學的數學題目也不是那么好玩的。
看看這個寒假作業:

   □ + □ = □
   □ - □ = □
   □ × □ = □
   □ ÷ □ = □
   
   (如果顯示不出來,可以參見【圖1.jpg】)
   
每個方塊代表1~13中的某一個數字,但不能重復。
比如:
 6  + 7 = 13
 9  - 8 = 1
 3  * 4 = 12
 10 / 2 = 5

以及: 
 7  + 6 = 13
 9  - 8 = 1
 3  * 4 = 12
 10 / 2 = 5

就算兩種解法。(加法,乘法交換律后算不同的方案)
 
你一共找到了多少種方案?


請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多余的內容或說明性文字。

  使用暴力搜索,每次找到一種12個數字的排列,判斷是否滿足上述四個等式要求,但是搜索空間太大了 運行了好久。代碼:

 1 #include <iostream>
 2 using namespace std;
 3 #define N 13
 4 int flag[20];
 5 int array[20];
 6 int sum=0;
 7 void dfs(int num){
 8     if(num==12){
 9         if(array[1]+array[2]!=array[3])
10             return;
11         if(array[4]-array[5]!=array[6])
12             return;
13         if(array[7]*array[8]!=array[9])
14             return;
15         if(array[12]*array[11]!=array[10])
16             return;
17         for(int i=1;i<13;i++){
18         cout<<array[i]<<" ";
19         if(i%3==0) cout<<endl;
20         }
21         cout<<endl;
22         sum++;
23         return;
24         }    
25     else{
26         for(int i=1;i<=13;i++){//確定i該處的數值 
27             if(flag[i]==0){//如果數字i未選擇 
28                 flag[i]=1;
29                 array[num+1]=i;
30                 dfs(num+1);
31                 flag[i]=0; 
32         } 
33     }
34     return;    
35     }
36 }
37 int main() {
38     dfs(0);
39         cout<<sum<<endl;
40     return 0;
41 
42 }

網上找到了更好的解決方案,見 http://m.blog.csdn.net/article/details?id=51039203 其中代碼如下:

 1 #include<iostream>
 2 #include<cstring>                               //包含memset(數組名,0/-1(只能是將數組中所有元素初始化這兩個數),sizeof(數組名))
 3 #include<algorithm>                             //算法頭文件,其中包含許多好用的庫函數
 4 using namespace std;
 5 int a[120]={-1},book[20]={0},sum=0;          //book數組是用來標記1-13哪個數已經被用過了,用過則記為1,否則記為0;
 6 void dfs(int x)
 7 {
 8     
 9     
10         if(x>3&&a[1]+a[2]!=a[3])           //如果前三個數已經被取出來但不符合題設條件,則返回重找
11             return;
12         if(x>6&&a[4]-a[5]!=a[6])           //若前三個數滿足第一條,看4-6個數是否滿足第二個條件
13             return;
14         if(x>9&&a[7]*a[8]!=a[9])             //同上
15             return;
16         if(x>12&&a[12]*a[11]==a[10])        //如果所有條件均滿足,則讓sum++
17         {
18             sum++;
19             return;
20         }
21     
22     for(int i=1;i<14;i++)                     //將1-13放入每一個格子中
23     {
24         if(book[i]==0)                     //若該數字沒被用過則可以用,進入下一步
25         {
26             a[x]=i;
27             book[i]=1;
28             dfs(x+1);
29             book[i]=0;
30         }
31     }
32     return;
33 }
34 int main()
35 {
36     memset(a,-1,sizeof(a));
37     dfs(1);
38     cout<<sum;
39     return 0;
40 }

 

#include <iostream>using namespace std;#define N 13int flag[20];int array[20];int sum=0;void dfs(int num){if(num==12){if(array[1]+array[2]!=array[3])return;if(array[4]-array[5]!=array[6])return;if(array[7]*array[8]!=array[9])return;if(array[12]*array[11]!=array[10])return;for(int i=1;i<13;i++){cout<<array[i]<<" ";if(i%3==0) cout<<endl;}cout<<endl;sum++;return;}else{for(int i=1;i<=13;i++){//確定i該處的數值 if(flag[i]==0){//如果數字i未選擇 flag[i]=1;array[num+1]=i;dfs(num+1);flag[i]=0; } }return;}}int main() {dfs(0);cout<<sum<<endl;return 0;
}


免責聲明!

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



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