题目描述:
现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:
□ + □ = □ 0 1 2
□ - □ = □ 3 4 5
□ × □ = □ 6 7 8
□ ÷ □ = □ 9 10 11
(如果显示不出来,可以参见【图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
就算两种解法。(加法,乘法交换律后算不同的方案)
你一共找到了多少种方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
分析:
我第一次做这道题,就是想着是全排列,判断每种情况是否符合条件,符合就计数一次,但是运行结果不尽人意,太慢了,后知后觉13位数的全排列似乎真的有点多,不像本次比赛的第三题,那个全排列起来规模小一点。
全排列不行,只好换法子,那么首选的就是DFS了,从第一位开始选,依次选到13位数,符合条件的计数,这个方法不同于全排列的地方在于,在选第三个数的时候,很大一部分组合因为不满足条件都被剪枝掉了,最后进入的都是符合条件的子树,出答案比较快。
代码如下:
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
int a[14];
bool visit[14]={false};
int sum=0;
int check();
void DFS(int k);
int main()
{
for(int i=1;i<=13;i++)
a[i]=0;
DFS(0);
cout<<sum;
return 0;
}
void DFS(int k)
{
if(k>13)
return;
if(k==12)
{
if(a[10]/a[11]==a[12]&&a[10]%a[11]==0)
sum++;
return;
}
if(k==9)
if(a[7]*a[8]!=a[9])
return;
if(k==6)
if(a[4]-a[5]!=a[6])
return;
if(k==3)
if(a[1]+a[2]!=a[3])
return;
for(int i=1;i<=13;i++)
{
if(!visit[i])
{
visit[i]=true;
a[k+1]=i;
DFS(k+1);
a[k+1]=0;
visit[i]=false;
}
}
}
int check()
{
}
答案:
64