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