HDU 4403 DFS

HDU 4403
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4403
题意:
对于一个数字串(长度小于等于15),问有多少种添加一个等号和多个或者0个+号的方法,使得等号两边值相等。
思路:
暴搜,枚举=号位置后,枚举每次有几个加号,然后这些加号放的位置。
源码:

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <ctime>
#include <climits>
#include <cassert>
#include <cmath>
#include <string>
#include <bitset>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#include <utility>
#include <numeric>
#define LL long long
#define gmax(a,b) ((a) > (b) ? (a) : (b))
#define gmin(a,b) ((a) < (b) ? (a) : (b))
#define MOD (1000000007)
using namespace std;
const int MAXN = 20;
char str[MAXN];
map<LL,LL>mm, mn;
LL ans;
int vis[MAXN];
void dfs1(int l, int r, int num)
{
    if(num == 0){
        LL lv = 0;
        LL temp = str[0] - '0';
        for(int i = 0 ; i < r ; i++){
            if(vis[i] == 0)  temp = temp * 10 + str[i + 1] - '0';
            else    lv += temp, temp = str[i + 1] - '0';
        }
//        for(int i = 0 ; i < r ; i++)
//            printf("vis[%d] = %d\n", i, vis[i]);
//        if(vis[r] == 1) printf("rhuasdad\n");
        lv += temp;
        mm[lv]++;
//        printf("l = %d, r = %d, lv = %I64d\n", 0, r, lv);
        return;
    }
    for(int i = l ; i <= r - num ; i++){
        vis[i] = 1;
        dfs1(i + 1, r, num - 1);
        vis[i] = 0;
    }
}
void solve1(int l, int r)
{
    int num = r - l;
    for(int i = 0 ; i <= num ; i++){
        dfs1(0, r, i);
    }
}
void dfs2(int now, int l, int r, int num)
{
    if(num == 0){
        LL lv = 0;
        LL temp = str[l] - '0';
        for(int i = l ; i < r ; i++){
            if(vis[i] == 0)  temp = temp * 10 + str[i + 1] - '0';
            else    lv += temp, temp = str[i + 1] - '0';
        }
//        if(vis[r] == 1) printf("rhuasdad\n");
//        for(int i = l ; i <= r ; i++)
//            printf("vis[%d] = %d\n", i, vis[i]);
        lv += temp;
//        printf("l = %d, r = %d, lv = %I64d\n", l, r, lv);
//        mn[lv]++;
//        if(mm[lv])  printf("lv = %I64d\n", lv);
//        ans += mn[lv] * mm[lv];
        ans += mm[lv];
        return;
    }
    for(int i = now ; i <= r - num; i++){
        vis[i] = 1;
        dfs2(i + 1, l, r, num - 1);
        vis[i] = 0;
    }
}
void solve2(int l, int r)
{
    int num = r - l + 1;
    for(int i = 0 ; i < num ; i++){
        dfs2(l, l, r, i);
    }
}
int main()
{
//    freopen("1004.in", "r", stdin);
    while(scanf("%s", str) != EOF && str[0] != 'E'){
        int len = strlen(str);
        ans = 0;
        memset(vis, 0, sizeof(vis));
        for(int i = 0 ; i < len - 1 ; i++){
            mm.clear();
            mn.clear();
//            dfs1(0, i, str[0] - '0');
//            dfs2(i + 1, len - 1, str[i + 1] - '0');
            solve1(0, i);
            solve2(i + 1, len - 1);
//            printf("\n");
        }
        printf("%I64d\n", ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值