题目如下:
这道题依然是一道dfs(要求输出方案数很明显用dfs呐)
首先一个模板贴上来:
void dfs()//参数用来表示状态
{
if(到达终点状态)
{
...//根据题意添加
return;
}
if(越界或者是不合法状态)
return;
if(特殊状态)//剪枝
return ;
for(扩展方式)
{
if(扩展方式所达到状态合法)
{
修改操作;//根据题意来添加
标记;
dfs();
(还原标记);
//是否还原标记根据题意
//如果加上(还原标记)就是 回溯法
}
}
}
这道题目有些特殊,在我们已经把十个符号确定的时候,我们才能考虑是否需要把方案数++,也就是只有算出总和才能确定是否满足条件。
这道题目的深搜函数只需要一个参数(sum)也就是目前已经确定的符号数量,当它大于9,再进入下一层dfs时,就可以判断这种情况是否满足条件啦。
判断是否满足条件也很简单,我们用0表示这里没有符号,1表示有个加号,2表示有个减号,用num[i]表示第i-1和第i个数之间的符号。
于是就:
if(sum==10)
{
int q=0,p;
for(int i=1;i<=9;)
{
if(num[i]==1)flag=1;
if(num[i]==2)flag=0;
p=i;
i++;
while(!num[i]&&i<=9)
{
p=p*10+i;
i++;
}
if(flag)q+=p;
else q-=p;
}
if(q==n)cnt++;
return;
}
注:flag表示是加法,!flag表示是减法。剩下的拓展方式就是这里放空,+,-,三种情况,参数全都是sum+1,dfs函数:
void dfs(int sum)
{
if(sum==10)
{
int q=0,p;
for(int i=1;i<=9;)
{
if(num[i]==1)flag=1;
if(num[i]==2)flag=0;
p=i;
i++;
while(!num[i]&&i<=9)
{
p=p*10+i;
i++;
}
if(flag)q+=p;
else q-=p;
}
if(q==n)cnt++;
return;
}
num[sum]=1;
dfs(sum+1);
num[sum]=2;
dfs(sum+1);
num[sum]=0;
dfs(sum+1);
return;
}
完整代码:
#include<bits/stdc++.h>
using namespace std;
int n,cnt=0;
int num[10];//0.1+2-
bool flag;
void dfs(int sum)
{
if(sum==10)
{
int q=0,p;
for(int i=1;i<=9;)
{
if(num[i]==1)flag=1;
if(num[i]==2)flag=0;
p=i;
i++;
while(!num[i]&&i<=9)
{
p=p*10+i;
i++;
}
if(flag)q+=p;
else q-=p;
}
if(q==n)cnt++;
return;
}
num[sum]=1;
dfs(sum+1);
num[sum]=2;
dfs(sum+1);
num[sum]=0;
dfs(sum+1);
return;
}
int main()
{
cin>>n;
num[1]=1;
dfs(2);
cout<<cnt<<endl;
return 0;
}
坑点:num[1]初值要赋1!
ov.