文章参考:
http://blog.csdn.net/liuchuo/article/details/51994221
http://blog.csdn.net/liu940204/article/details/51005414
http://blog.csdn.net/liu940204/article/details/51005463
http://blog.csdn.net/qq_32183461/article/details/50705953
http://blog.csdn.net/chen_tongsheng/article/details/55211772
http://blog.csdn.net/summonlight/article/details/61427968
一、题目
寒假作业
现在小学的数学题目也不是那么好玩的。看看这个寒假作业:
□ + □ = □
□ - □ = □
□ × □ = □
□ ÷ □ = □
每个方块代表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,说实话,才看了一天的DFS,只知道它是深度优先搜索算法,对图进行遍历。又看了几个蓝桥杯dfs方面的例题,对dfs的了解就只有这么多。
#include<stdio.h>
int a[13] = { 0 };//标记12个位置对应的数,a[0]不用
int book[14] = { 0 };//标记1-13有没有被使用过,book[1]=0表示数值1没有被使用,book[1]=1表示数值1被使用了,book[0]不用
int count = 0;//满足条件的总格式初始化为0
void dfs(int x)
{
if (x > 12)//如果12个数都已经填满了,进行判断
{
if ((a[10] / a[11] == a[12]) && (a[10] % a[11] == 0)&& (a[7] * a[8] == a[9]) && (a[1] + a[2] == a[3]) && (a[4] - a[5] == a[6]))
{
count++;//满足条件,数量加一
for (int i = 1; i <= 12; i++)//输出满足条件的值,查看结果
{
printf("%d ", a[i]);
}
printf("\n");
return;
}
}
for (int i = 1; i <= 13; i++)//从数字1到13,看有没有没用过的数字,没有用过就填入当前格子
{
if (book[i] == 0)//表示i这个数字没有用过
{
book[i] = 1;//将book[i]置1,表示i这个数被用了
a[x] = i;//当前格子值a[x]置为i
dfs(x + 1);//进行下一次搜索,填入下一个数字
book[i] = 0;//从后向前回溯,将book[i]置0。这一行非常重要,千万不能掉。
}
}
}
int main()
{
dfs(1);
printf("%d\n", count);
return 0;
}
看了六角填数和方格填数的例子,仿照着写的。最开始程序运行的时候半天不出结果,心理很担心是不是写错了,运行了关闭,关闭了运行。后来看了其他人寒假作业的例子,才发现直接这样一下子判断所有条件,运行次数太多,速度太慢。回寝室之后,好奇到底要运行多久,就搞台式机跑了一下,20多分钟出的结果。没有想象中那么久,但就普通程序来说,也等不起。
补充:20多分钟是Debug的结果,后来换成Release,10分钟出结果,但还是有点久。
二、加一点初始条件看看
因为直接运行要很久,想起了六角填数,那题有12个数,3个数的初始值已经定了,程序运行很快就出结果。就差几个出,运行时间差别怎么就那么大了??就想着能不能像六角填数那样,我自己先给他赋值一个初始条件,看看运行结果是那样,运行时间要多久。
根据题目给了实例,我令a[1]=6,a[2]=7,a[3]=13,相应地book[6]=1,book[7]=1,book[13]=1,预期结果应该是16。
//加初始条件
#include<stdio.h>
int a[13] = { 0 };//标记12个位置对应的数,a[0]不用
int book[14] = { 0 };//标记1-13有没有被使用过,book[1]=0表示数值1没有被使用,book[1]=1表示数值1被使用了,book[0]不用
int count = 0;//满足条件的总格式初始化为0
void dfs(int x)
{
if (x == 1 || x == 2 || x == 3)//直接进行下一次搜索
{
dfs(x + 1);
return;
}
if (x > 12)//如果12个数都已经填满了,进行判断
{
if ((a[10] / a[11] == a[12]) && (a[10] % a[11] == 0) && (a[7] * a[8] == a[9]) && (a[1] + a[2] == a[3]) && (a[4] - a[5] == a[6]))
{
count++;//满足条件,数量加一
for (int i = 1; i <= 12; i++)//输出满足条件的值,查看结果
{
printf("%d ", a[i]);
}
printf("\n");
return;
}
}
for (int i = 1; i <= 13; i++)//从数字1到13,看有没有没用过的数字,没有用过就填入当前格子
{
if (book[i] == 0)//表示i这个数字没有用过
{
book[i] = 1;//将book[i]置1,表示i这个数被用了
a[x] = i;//当前格子值a[x]置为i
dfs(x + 1);//进行下一次搜索,填入下一个数字
book[i] = 0;//从后向前回溯,将book[i]置0。这一行非常重要,千万不能掉。
}
}
}
int main()
{
a[1] = 6;
a[2] = 7;
a[3] = 13;
book[6] = 1;
book[7] = 1;
book[13] = 1;
dfs(1);
printf("%d\n", count);
return 0;
}
基本秒出结果
感觉自己好弱智,别人都说这是基本入门算法。。。呜呜呜。
三、分开判断
看了一下别人的代码,分开判断,秒出结果。
//三、分开判断
#include<stdio.h>
double a[13] = {0};
int book[14] = {0};
int count = 0;
int j = 0;
void dfs(int x)
{
if (x == 4)
{
if (a[1] + a[2] != a[3])
return;
}
if (x == 7)
{
if (a[4] - a[5] != a[6])
return;
}
if (x == 10)
{
if (a[7] * a[8] != a[9])
return;
}
if (x > 12)
{
if (a[10] / a[11] == a[12])
{
count++;
}
return;
}
for (int i = 1; i <= 13; i++)
{
if (book[i] == 0)
{
book[i] = 1;
a[x] = i;
dfs(x + 1);
book[i] = 0;
}
}
}
int main()
{
dfs(1);
printf("%d\n", count);
return 0;
}
四、全排列
今天下午,接触到全排列算法。同学用java写的,2分钟就跑出结果了。我就照着写了一下。
//自己全排列
#include<stdio.h>
int a[14] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13};
int count = 0;
void swap(int *a, int*b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void FullPermutation(int x)
{
if (x >= 13)
{
if ((a[11]*a[12]==a[10]) && (a[7] * a[8] == a[9]) && (a[1] + a[2] == a[3]) && (a[4] - a[5] == a[6]))
{
count++;//满足条件,数量加一
for (int i = 1; i <= 12; i++)//输出满足条件的值,查看结果
{
printf("%d ", a[i]);
}
printf("\n");
return;
}
}
for (int i = x; i < 14; i++)
{
swap(&a[i], &a[x]);
FullPermutation(x + 1);
swap(&a[i], &a[x]);
}
}
int main(void)
{
FullPermutation(1);
printf("%d\n", count);
return 0;
}
程序写好后,在VS中运行,十几分钟半天不出结果。大爷的,别人java的2分钟就出结果了,我的C怎么这么久。就胡乱改代码,还是不行。后来在网上百度,无意中发现VS中Release比Debug要看,就换成了Release试试,结果2分钟就出结果了。呜呜呜,不容易呀。
`