HDU 4403 dfs

Problem Description

Aoshu is very popular among primary school students. It is mathematics, but much harder than ordinary mathematics for primary school students. Teacher Liu is an Aoshu teacher. He just comes out with a problem to test his students:

Given a serial of digits, you must put a '=' and none or some '+' between these digits and make an equation. Please find out how many equations you can get. For example, if the digits serial is "1212", you can get 2 equations, they are "12=12" and "1+2=1+2". Please note that the digits only include 1 to 9, and every '+' must have a digit on its left side and right side. For example, "+12=12", and "1++1=2" are illegal. Please note that "1+11=12" and "11+1=12" are different equations.

Input

There are several test cases. Each test case is a digit serial in a line. The length of a serial is at least 2 and no more than 15. The input ends with a line of "END".

Output

For each test case , output a integer in a line, indicating the number of equations you can get.

Sample Input
1212
12345666
1235
END
 

Sample Output
2
2
0

题意:
 给你一串数字,你要在该串数字中间的某些位置加一个等号=和一个或多个+号或0个,使得那串数字编成一个等式。问你有多少种方式?

所以我们只需要先枚举=的位置mid,然后分别计算等号左边[0,mid-1],和等号右边[mid,len-1]可能的值即可。

        注意我们先构造等号左边的值,当构造完当前左边值的基础上(即本dfs_left内),再去构造右边,看看有多少个右值等于该特定的左值。

        代码中预处理了value[i][j]表[i,j]区间的连续数字构造的值。
代码:

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn= 20;
char num[maxn];
long long value[maxn][maxn];
int ans;//解
int len;//输入字符长度
long long get_value(int x,int y)
{
    long long sum=0;
    for(int i=x;i<=y;i++)
        sum = sum*10+num[i]-'0';
    return sum;
}
void dfs_right(int pos,int left_sum,int sum)//left_sum左边已经算出来的和
{
    if(pos>=len)
    {
        if(left_sum==sum) ans++;
    }
    else for(int i=pos;i<len;i++)
        dfs_right(i+1,left_sum,sum+value[pos][i]);
}
void dfs_left(int pos,int sum,int mid)//pos当前位置,sum当前和,mid当前=号位置
{
    if(pos>=mid)//处理完左边,开始处理右边了
    {
        dfs_right(mid,sum,0);
    }
    else for(int i=pos;i<mid;i++)//sum+本段值+下一段,即本段值是[pos,i]之间数的值,这之间没+号
        dfs_left(i+1,sum+value[pos][i],mid);
}
int main()
{
    while(scanf("%s",num)==1&&num[0]!='E')
    {
        ans=0;
        len=strlen(num);
        for(int i=0;i<len;i++)
        for(int j=i;j<len;j++)
            value[i][j]=get_value(i,j);
        for(int mid=1;mid<len;mid++)//mid是等号位置,也即右边第一个数的位置
            dfs_left(0,0,mid);
        printf("%d\n",ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值