2016蓝桥杯C++A:寒假作业(详细解析)

六、题目:寒假作业:
现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:

□ + □ = □
□ - □ = □
□ × □ = □
□ ÷ □ = □

每个方块代表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个数中选12个填到方框里面,是一个全排列问题。最终13个数都会填完

  • 代码:
    第一段代码,虽然能够运行出结果,但是花费时间需要将近1分钟,做填空题可以用。能运行出答案就行。

#include<iostream>
using namespace std;

int a[]={1,2,3,4,5,6,7,8,9,10,11,12,13};
int ans;
bool check(){
	if(a[0]+a[1]==a[2]&&
	a[3]-a[4]==a[5]&&
	a[6]*a[7]==a[8]&&
	a[9]%a[10]==0&&
	a[9]/a[10]==a[11])
	return true;
	return false;
}
int f(int k){
	if(k==13){ //当数字为13的时候,可以不同return,因为后面for循环它通不过 
		if(check())
		ans++;
	}
	for(int i=k;i<13;i++){
		{
		int t=a[i];
		a[i]=a[k];
		a[k]=t;
	}
	continue;
f(k+1);
{
		int t=a[i];  //回溯,返回原来状态 
		a[i]=a[k];
		a[k]=t;
}
}
int main(){
	f(0);
	cout<<ans<<endl; 
	return 0;
}

改进方法:提前检知
{int t=a[i];a[i]=a[k];a[k]=t;};
这一行确定了k的位置

  • 代码:
#include<iostream>
using namespace std;

int a[]={1,2,3,4,5,6,7,8,9,10,11,12,13};
int ans;
bool check(){
	if(a[0]+a[1]==a[2]&&
	a[3]-a[4]==a[5]&&
	a[6]*a[7]==a[8]&&
	a[9]%a[10]==0&&
	a[9]/a[10]==a[11])
	return true;
	return false;
}
int f(int k){
	if(k==13){ //当数字为13的时候,可以不同return,因为后面for循环它通不过 
		if(check())
		ans++;
	}
	for(int i=k;i<13;i++){
		{int t=a[i];a[i]=a[k];a[k]=t;}
		//提前检知,节省运行时间 
	if((k==2&&a[0]+a[1]!=a[2])||k==5&&a[3]-a[4]!=a[5]){  //判断符合条件,再进行递归,不符合直接退出 
	{int t=a[i];a[i]=a[k];a[k]=t;}
	continue;
}
f(k+1);
{int t=a[i];a[i]=a[k];a[k]=t;}//回溯,返回原来状态
}
}
int main(){
	f(0);
	cout<<ans<<endl; 
	return 0;
}

在这里插入图片描述
如果觉得答案可能有问题,可以把所有的符合条件的列举出来

  • 代码:
#include<iostream>
using namespace std;

int a[]={1,2,3,4,5,6,7,8,9,10,11,12,13};
int ans;
bool check(){
	if(a[0]+a[1]==a[2]&&
	a[3]-a[4]==a[5]&&
	a[6]*a[7]==a[8]&&
	a[9]%a[10]==0&&
	a[9]/a[10]==a[11])
	return true;
	return false;
}
int f(int k){
	if(k==13){ //当数字为13的时候,可以不同return,因为后面for循环它通不过 
		if(check()){
		printf("%d+%d=%d  %d-%d=%d %d*%d=%d %d/%d=%d\n"); 
		ans++;
	}
}
	for(int i=k;i<13;i++){
		{int t=a[i];a[i]=a[k];a[k]=t;}
		//提前检知,节省运行时间 
	if((k==2&&a[0]+a[1]!=a[2])||k==5&&a[3]-a[4]!=a[5]){  //判断符合条件,再进行递归,不符合直接退出 
	{int t=a[i];a[i]=a[k];a[k]=t;}
	continue;
}
f(k+1);
{int t=a[i];a[i]=a[k];a[k]=t;}//回溯,返回原来状态
}
}
int main(){
	f(0);
	cout<<ans<<endl; 
	return 0;
}

这是列举的部分结果
在这里插入图片描述

发布了137 篇原创文章 · 获赞 7 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/gl620321/article/details/105166552