对DFS还是很头疼,搞不懂它是怎么运行的,有时候看着别人写的DFS看着看着就晕了,还得多做做这类的题目,上次网赛就有一道DFS暴搜,不会啊。。。。
本题的题意为给定一个由数字组成的字符串,向里面加入一个等号,和任意个加号,使得等式成立,问一共有多少种方案。
思路为枚举等号出现的位置,用equ表示,则1<=equ<=len-1, 也就是把等号加在第equ个数字后面,紧跟着第equ个数字。然后先DFS等号左边所有可能出现的情况,对应每个左边所出现的和lsum,再DFS等号右边所有可能出现的情况rsum,如果 rsum==lsum,那么有一种方案可行。
总结:通过DFS来搜出等号左边所有的状态,每一种状态压入栈中,然后从栈中取状态,再去DFS等号右边所有的状态,状态相等,则有一种方案可行。
#include
#include
#include
using namespace std;
char str[17];
int val[17][17];
int len;
int ans;
void cal()
{
memset(val,0,sizeof(val));
for(int i=1;i<=len;i++)
for(int j=i;j<=len;j++)
{
for(int k=i;k<=j;k++)
val[i][j]=val[i][j]*10+(str[k]-'0');
}
}
void dfsr(int lsum,int pos,int rsum)//dfs等号后边可能出现的情况
{
if(pos>len)
{
if(rsum==lsum)
ans++;
return;
}
for(int k=pos;k<=len;k++)//注意是<=,因为最后一位也属于等号后边
dfsr(lsum,k+1,rsum+val[pos][k]);//注意是k+1
}
void dfsl(int equ,int pos,int lsum)//dfs等号左边可能出现的情况,每种情况对应一个lsum(等号左边的和)
{
if(pos>equ)//当等号左边的数字的位置大于等号的位置时,搜索等号后边
dfsr(lsum,equ+1,0);
for(int k=pos;k<=equ;k++)//注意是<=,equ代表的是等号加在第equ个数字后面
dfsl(equ,k+1,lsum+val[pos][k]);
}
int main()
{
while(cin>>(str+1)&&str[1]!='E')
{
ans=0;
len=strlen(str+1);
cal();
int equ;
for(equ=1;equ<=len-1;equ++)
dfsl(equ,1,0);
cout<