六、题目:寒假作业:
现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:
□ + □ = □
□ - □ = □
□ × □ = □
□ ÷ □ = □
每个方块代表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;
}
这是列举的部分结果