1. 程式人生 > >HDU 4403 dfs

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;
}