第七届蓝桥杯_第六题_寒假作业

文章参考:

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分钟就出结果了。呜呜呜,不容易呀。

`

猜你喜欢

转载自blog.csdn.net/hhhhhyyyyy8/article/details/79620381