原题链接
题目大意
输入一个自然数 n ( n ≤ 9 ) n(n\le 9) n(n≤9),利用 1 ∼ n 1\sim n 1∼n选择合并(加空格),填加号,填减号,输出所有得数为0的算式。
解题思路
这是一道数据很小的题目,考虑dfs(深搜),我们可以记录每次的和,由于有空格,所以我们不只要有这些变量。空格会改变当前的和,不过是变多还是变少?是增加多少,减少多少?这些,都得用变量记录下来。
void dfs(int number/*当前数字,(为增加减少的数量记录)*/,int dep/*深度,枚举到第几个,int a/*当前的和*/,int z/*当前状态(上一次是加还是减,1或-1)*/)
{
if(dep>=n){
//结束条件
if(a==0){
//输出答案条件
cout<<1;
for(int i=1;i<=n-1;i++)
cout<<ans[i]<<i+1;
cout<<endl;
}
return;
}
ans[dep]=' ';//按照题目要求,先‘ ’,再‘+’,再‘-’
dfs(number*10+dep+1,dep+1,a+z*(9*number+dep+1),z);//dep+1代表当前的数,先用已有的数拼上当前的数,在把答案加入和里,由于加是1,减是-1,所以9*number+dep+1(答案变化)再乘z,就可以表示为当前和的变化
ans[dep]='+';
dfs(dep+1,dep+1,a+dep+1,1);//放入加号,当前数为dep+1,和加上dep+1,状态为1
ans[dep]='-';
dfs(dep+1,dep+1,a-dep-1,-1);//放入加号,当前数为dep+1,和减去dep+1,状态为-1
return;
}
代码实现
#include<iostream>
#include<cmath>
#include<fstream>
#include<cstring>
#include<string>
#include<cstdio>
#include<ctime>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
using namespace std;
char ans[100];
int n;
void dfs(int number/*当前数字,(为增加减少的数量记录)*/,int dep/*深度,枚举到第几个,int a/*当前的和*/,int z/*当前状态(上一次是加还是减,1或-1)*/)
{
if(dep>=n){
//结束条件
if(a==0){
//输出答案条件
cout<<1;
for(int i=1;i<=n-1;i++)
cout<<ans[i]<<i+1;
cout<<endl;
}
return;
}
ans[dep]=' ';//按照题目要求,先‘ ’,再‘+’,再‘-’
dfs(number*10+dep+1,dep+1,a+z*(9*number+dep+1),z);//dep+1代表当前的数,先用已有的数拼上当前的数,在把答案加入和里,由于加是1,减是-1,所以9*number+dep+1(答案变化)再乘z,就可以表示为当前和的变化
ans[dep]='+';
dfs(dep+1,dep+1,a+dep+1,1);//放入加号,当前数为dep+1,和加上dep+1,状态为1
ans[dep]='-';
dfs(dep+1,dep+1,a-dep-1,-1);//放入加号,当前数为dep+1,和减去dep+1,状态为-1
return;
}
int main()
{
cin>>n;
dfs(1,1,1,1);//初始条件,和为1,因为第一项无法加负号,就像加了加号一样
return 0;
}
样例
输入
7
输出
1+2-3+4-5-6+7
1+2-3-4+5+6-7
1-2 3+4+5+6+7
1-2 3-4 5+6 7
1-2+3+4-5+6-7
1-2-3-4-5+6+7