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

posted @ 2017-02-14 18:31  Elaine_DWL  阅读(2586)  评论(0编辑  收藏  举报