题目描述
给你 n 根火柴棍,你可以拼出多少个形如A+B=C 的等式?等式中的 A、B、C 是用火柴棍拼出的整数(若该数非零,则最高位不能是 0)。用火柴棍拼数字0∼9的拼法如图所示:
注意:
- 加号与等号各自需要两根火柴棍;
- 如果 A
B,则 A+B=C 与B+A=C 视为不同的等式(A,B,C≥0);
- n 根火柴棍必须全部用上。
输入格式
一个整数 n(1≤n≤24)。
输出格式
一个整数,能拼成的不同等式的数目。
这道题相较普通dfs题目来说,多加一个数组记录数字需要的火柴棒数量即可,需要着重注意的是,A、B可能是两位数或者更大,所以需要一个函数计算多位数需要的火柴棒数量。由于火柴棒数量最大是24,除去+、=组成三个数字的火柴棒数量最大是20。经过推理,最大的数是711,711+0=711,需要刚好24个火柴棒。
所需变量一共6个:
n:火柴棒数量
sum:当前位置所需火柴棒的数量
x:(一共三个数字)当前操作的数字编号
ans:输出的答案(方案数)
num数组:用来记录各个数字所需火柴棒数量
op数组:暂时储存当前方案所选的数
#include "iostream"
using namespace std;
int n,num[10]={6,2,5,5,4,5,6,3,7,6};
int op[5],ans;
int cal(int x){
if(num[x])return num[x];//一个小小的剪枝
else{
int temp=0;
while(x){//每次将个位的树提取出来计算所需火柴棒数量
temp+=num[x%10];
x/=10;
}
return temp;
}
}
void dfs(int x,int sum){
if(sum>n)return;//剪枝,sum>n不必再进行
if(x>3){
if(sum+4==n&&op[1]+op[2]==op[3])ans++;符合题目条件,方案数加一
return;
}
for(int i=0;i<=1000;i++){//1000足矣
op[x]=i;
dfs(x+1,sum+cal(i));//搜索下一位,并将火柴棒数传入
op[x]=0;//回溯
}
}
int main(){
cin>>n;
dfs(1,0);
cout<<ans;
}
不理解可以尝试画一下递归线索树加快理解。
当然,这个代码是不能将题目AC的,把num数组开到1000就能顺利AC,具体什么原因我也搞不清,有知道的可以评论一下。