HDU 4403 A very hard Aoshu problem DFS

来源:互联网 发布:诺思星被淘宝大学开除 编辑:程序博客网 时间:2024/05/22 05:21

problem statement

这道题给我们一个不超过15位的整数 让我们在其中加等号或者加号
如果加完符号后符合计算结果 那么计数 最后输出所有的情况

problem analysis

这道题其实就是想办法遍历所有情况
把合法的记录下来 最终输出就得到解
如何枚举呢
我们可以枚举等号的位置 等号左边dfs一下 等号右边dfs一下
最后最后看两遍结果是否一样 一样就记录++
最后左右两遍可以搞两个dfs
如何dfs 就是枚举加号的位置把每一种情况都遍历到就好了

problem code

#include<bits/stdc++.h>using namespace std;char a[20];int num[20][20],len,ans;void rdfs(int lsum,int pos,int rsum){    if(pos == len){// 如果走完了所有的数 那么判断左是否等于右 如果等于 就记录结果        if(lsum==rsum)ans++;        return;    }    for(int i=pos;i<len;i++){        rdfs(lsum,i+1,rsum+num[pos][i]); //这就相同与ldfs    }}void ldfs(int k,int mid,int lsum){//k表示当前位置 mid表示等号位置 lsum记录左边的和            if(k==mid){// 如果当前位置到mid 我们就搜索右边的和         rdfs(lsum,mid,0);    }    for(int i=k;i<mid;i++){        ldfs(i+1,mid,lsum+num[k][i]);// 这里就会把所有的加号情况遍历 对每一个位置 下一个加号在k到mid的任何位置都会尝试一遍 也就是对于当前位置 下一个加号的位置都搜索一遍 可以枚举到所有的加号情况     }//左半部分枚举加号 }int main(){    while(scanf("%s",a)){        len = strlen(a);        if(strcmp(a,"END")==0)break;        for(int i=0;i<len;i++){            for(int j=0;j<len;j++){                int sum=0;                for(int k=i;k<=j;k++)sum = sum*10+(a[k]-'0');//预处理把任意i到j的数的大小求出来                num[i][j] = sum;            }        }        for(int i=1;i<len;i++)            ldfs(0,i,0);        printf("%d\n",ans);        ans=0;    }    return 0;}