TWO+TWO=FOUR
题目含义
t w o ,f u r分别是0,1,2,3,4,5,6,7,8,9里面的六个数字。我们要找到它们组合使得two+two=four的等式成立,即
~~
two
+ two
----------
~
four
解题思路
全排列枚举
1.for循环嵌套有点麻烦,我们直接使用c++自带的全排列函数来完成(next_permutation)
2.我们使用map来保证不会有重复的组合,因为10个数字我们只使用了前6个,所以全排列会有重复项
3.通过f=0,t=0 continue适当提速
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
int num[10];
int ans=0;
map<int,int> m;
int main(){
for(int i=0;i<10;i++) num[i]=i;
do{
if(num[5]==0||num[0]==0) continue;
int t=num[0];
int w=num[1];
int o=num[2];
int r=num[3];
int u=num[4];
int f=num[5];
int two=t*100+w*10+o;
int four=f*1000+o*100+u*10+r;
if(two*2==four&&!m.count(two)){
cout<<" "<<t<<w<<o<<endl;
cout<<"+"<<t<<w<<o<<endl;
cout<<f<<o<<u<<r<<endl;
cout<<"*****************"<<endl;
ans++;
m[two]=1;
}
}while(next_permutation(num,num+10));
cout<<"一共有"<<ans<<"种解答"<<endl;
return 0;
}
// two
// two
//four
// owtruf
深搜
深搜递归函数参数解释:
vector a;//用来存放组合的数字
map m; //用存放哪些数字已经用过了,这样确保了数字的唯一性
cnt; //记录了当前a的深度,也可以没有这个参数,用a.size()来代替
注意点:
1.递归的a,m,cnt是需要回溯的,cnt是用的传参+1,所以不用特意再减一,因为cnt+1没有改变cnt的值
2.剪枝的说明
一. f=1,说明t一定要大于5
二. 结果一定满足oo=r||r+10
三. 结果一定满足ww+(o*o)%10=u||u+10
#include<iostream>
#include<vector>
#include<map>
using namespace std;
int ans=0;//最终的解法
void check(vector<int> num){
//f一定是1的 f=1
int t=num[0];
int o=num[1];
int r=num[2];
int w=num[3];
int u=num[4];
int two=t*100+w*10+o;
int four=1000+o*100+u*10+r;
if(two*2==four){
cout<<" "<<t<<w<<o<<endl;
cout<<"+"<<t<<w<<o<<endl;
cout<<1<<o<<u<<r<<endl;
cout<<"*****************"<<endl;
ans++;
}
}
void dfs(vector<int> a,map<int,int> m,int cnt){
if(cnt==5) {
check(a);return ;
}
//深搜剪枝1 大于5才能进1
if(cnt==1&&a[0]<6) return ;
//深搜剪枝2 个位数不满足要求
if(cnt==3&&a[1]*2!=a[2]&&a[1]*2!=10+a[2]) return;
//深搜剪枝3 十位数不满足要求
if(cnt==5&&a[3]*2+(a[1]*2)%10!=a[4]&&a[3]*2+(a[1]*2)%10!=10+a[4]) return ;
for(int i=0;i<10;i++){
if(i==1) continue;//f是1
if(!m.count(i)){
a.push_back(i);
m[i]=1;
dfs(a,m,cnt+1);
//回溯
a.pop_back();
m.erase(m.find(i));
}
}
}
int main(){
vector<int> a;
map<int,int> m;
int cnt=0;
dfs(a,m,cnt);
cout<<"一共有"<<ans<<"种解答"<<endl;
return 0;
}
结果展示
其中深搜运行0.009s
其中全排运行0.137s
如何测试运行时间
//计算一段程序运行的时间
#include<iostream>
#include<ctime>
using namespace std;
int main()
{
clock_t startTime,endTime;
startTime = clock();//计时开始
for (int i = 0; i < 2147483640; i++)
{
i++;
}
endTime = clock();//计时结束
cout << "The run time is: " <<(double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;
return 0;
}