HDU:4403 A very hard Aoshu problem

这要要用回溯法来做。好久没做回溯的题了,几乎忘光了~
但是我开始看到这个题的时候居然一点思路都没有。回想以前做过的回溯题,八皇后,数学表达式,全排列都有一个特点,都是试图枚举出全部情况,只不过有些不合要求的情况被直接否了。这种枚举是层次性的,可以说是无限个循环,不是几个循环可以写出来的。


这道题,放的加号没有限制,等号只能放一个。
先写一个循环枚举等号的位置,然后就进入递归可以枚举加号的位置。

好好领会吧~

这里有一些注意的地方。比如说判断等式左右是否相等的方法是当进入等号右边以后原和取其相反数,最后看结果是否为0即可。
字符串转数字也比较有技巧,以前我总是用atol这些函数,但是这样有个坏处必须遍历字串得到其始末位置才能截取,这份代码用了另一个办法。

比如说数字ABCD 其实就等于 ((A*10+B)*10+C)*10+D ,这样可以边遍历边计算。



#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
string str;
int cnt=0;
void dfs(int cur,int mid,int sum)
{
    if(cur==str.size())
    {
        if(sum==0) cnt++;
        return;
    }
    if(cur==mid) sum=-sum;
    int k,t=0;
    if(cur<mid) k=mid;
    else k=str.size();
       for(int i=cur;i<k;++i)
     {
         t=t*10+str[i]-'0';
         dfs(i+1,mid,sum+t);
     }
}
int main()
{
    while(cin>>str&&str!="END")
    {
        cnt=0;
        for(int i=1;i<str.size();++i)
          dfs(0,i,0);
        cout<<cnt<<endl;
    }
    return 0;
}


你可能感兴趣的:(枚举,DFS,回溯法)