寒假作业问题(DFS方法)
作者:互联网
问题:
寒假作业
现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:
每个方块代表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
就算两种解法。(加法,乘法交换律后算不同的方案)
你一共找到了多少种方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
分析:
这个问题和上次写的那个凑算式问题有异曲同工之妙,那个只有一个等式,而这个题目四个等式必须都满足,问题规模较大。由此可见,这道题目是较为复杂的。
但是解题思路是一样的:第一种办法:穷举搜索,直接列出所有可能,再验证是否满足这四个等式,穷举搜索的方法有暴力和全排列;第二种办法:采用深度搜索优先思想,用递归方法,列出可能的解。
在解这道问题时要同时满足四个条件,则列出一个算式可能之后就判定是否符合条件,假如符合的话,继续进行枚举;假若不符合,直接返回,不用再进行之后的枚举。这样的话能够节省时间,提高效率。
代码:
DFS解决:
#include<iostream>
using namespace std;
int total = 0, num[14], flag[14]; //舍弃第0位不用,1-13位,flag为标志位
void dfs(int n)
{
if (n >= 14) //不满足,直接退出
return;
else if (n == 4 && num[1] + num[2] != num[3]) //列出一个可能的算式之后判定其是否满足对应的判定条件
return;
else if (n == 7 && num[4] - num[5] != num[6])
return;
else if (n == 10 && num[7] * num[8] != num[9])
return;
else if (n == 13)
{
if (num[12] * num[11] == num[10])
total++;
}
for (int i = 1; i < 14; i++)
{
if (flag[i] == 0) //标志位为0,表示该数字还未被使用,也就是顶点未被访问
{
num[n] = i;
flag[i] = 1;
dfs(n + 1); //递归
flag[i] = 0;
}
}
}
int main()
{
dfs(1);
cout << total << endl;
return 0;
}
感悟:
对于这种取不同的数字来建立等式,dfs大都能快速而有效的解决。经过这两天的练习,dfs算法已初窥门径,还需要继续加强练习。
标签:13,return,14,dfs,flag,num,DFS,寒假作业,方法 来源: https://blog.csdn.net/Crazy__1/article/details/88668612