Hut 1997 Seven tombs

题目连接:http://openoj.awaysoft.com/JudgeOnline/problem.php?id=1997

表达式树的应用。

本题可以使用中缀表达式转后缀表达式,然后枚举求解。也可以直接构建表达式树进行枚举求解。

关键是寻找最后计算的运算符,然后递归建立表达式树。

具体做法参考刘汝佳《算法竞赛入门经典》198页。

另外练习:next_permutation()

 

#include <iostream>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>

#include <vector>

#include <algorithm>

using namespace std;



#define maxn 105



int lch[2][maxn];

int rch[2][maxn];

string op[2][maxn];

//节点数

int nc = 0;



int f[7] = {1,2,3,4,5,6,7};



//建立表达式树

int build_tree(char *s,int x,int y,int t)

{

    int p = 0;

    int c1 = -1;

    int c2 = -1;

    int flag = 0;

    int u = 0;

    for(int i=x; i<y; i++)

    {

        if(s[i] == '(' || s[i] == ')' || s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/')

        {

            flag = 1;

            break;

        }

    }

    //没有运算符了

    if(flag == 0)

    {

        u = ++nc;

        lch[t][u] = 0;

        rch[t][u] = 0;

        for(int i=x; i<y; i++)

        {

            op[t][u].push_back(s[i]);

        }

        return u;

    }

    for(int i=x; i<y; i++)

    {

        switch(s[i])

        {

        case '(':

            p++;

            break;

        case ')':

            p--;

            break;

        case '+':

        case '-':

            if(!p) c1 = i;

            break;

        case '*':

        case '/':

            if(!p) c2 = i;

            break;



        }

    }

    if(c1<0) c1 = c2;

    if(c1<0) return build_tree(s,x+1,y-1,t);

    u = ++nc;





    lch[t][u] = build_tree(s,x,c1,t);

    rch[t][u] = build_tree(s,c1+1,y,t);

    op[t][u].push_back(s[c1]);

    return u;

}

int num(int u,int t)

{

    int temp = 1;

    int sum = 0;

    if(op[t][u][0] == '+')

    {

        return num(lch[t][u],t) + num(rch[t][u],t);

    }

    if(op[t][u][0] == '-')

    {

        return num(lch[t][u],t) - num(rch[t][u],t);

    }

    if(op[t][u][0] == '*')

    {

        return num(lch[t][u],t) * num(rch[t][u],t);

    }

    for(int i=op[t][u].size()-1; i>=0; i--)

    {

        sum += f[op[t][u][i] - 'A'] * temp;

        temp *= 10;

    }

    return sum;

}

void init()

{

    for(int i=0;i<2;i++)

    {

        for(int j=0;j<maxn;j++)

        {

            op[i][j].clear();

        }

    }

}

int main()

{

#ifndef ONLINE_JUDGE

    freopen("in.txt","r",stdin);

#endif

    char expression[105];

    char left_exp[105];

    char right_exp[105];



    while(scanf(" %s",expression)!=EOF)

    {

        init();

        int len = strlen(expression);

        int len1 = 0,len2 = 0;

        int flag = 0;

        for(int i=0; i<len; i++)

        {

            if(expression[i] == '=')

            {

                flag = 1;

                continue;

            }

            if(flag == 0) left_exp[len1++] = expression[i];

            else right_exp[len2++] = expression[i];

        }

        left_exp[len1] = '\0';

        right_exp[len2] = '\0';



        nc = 0;

        int node1 = build_tree(left_exp,0,len1,0);

        nc = 0;

        int node2 = build_tree(right_exp,0,len2,1);

        int lsum,rsum;

        do

        {

            lsum=num(node1,0);

            rsum=num(node2,1);

            if(lsum==rsum)

                break;

        }

        while(next_permutation(f,f+7));

        for(int i=0; i<len; i++)

        {

            if(expression[i]>='A' && expression[i]<='G')

                printf("%d",f[expression[i]-'A']);

            else

                printf("%c",expression[i]);

        }

        printf("\n");



    }

}


 

 

你可能感兴趣的:(T)