HDOJ-4192-Guess the Numbers【用栈实现计算器】

HDOJ-4192-Guess the Numbers

                Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Problem Description
John has never been very good at maths. Due to his bad grades, his parents have sent him to the Academic Coalition of Mathematics (ACM). Despite the large amount of money his parents are spending on the ACM,
John does not pay much attention during classes. However, today he has begun to think about all the e ffort his parents are putting into his education, and he has started to feel somewhat… guilty. So he has made a decision: he is going to improve his maths grades!

However, no sooner had he resolved to pay attention than the lesson ended. So the only thing he has been able to do is to hurriedly copy the content of the blackboard in his notebook. Today, the teacher was explaining basic arithmetic expressions with unknowns. He vaguely remembers that his classmates have been substituting values into the unknowns to obtain the expressions’ results. However, in all the hurry, John has only written down expressions, values and results in a messy fashion. So he does not know which value comes with each unknown, or which result goes with each expression.
That is the reason he needs your help: he wants to know, given an expression, some values and a result, whether it is possible or not to assign those values to the unknowns in order for the expression to evaluate to the given result. The particular assignment of values does not matter to John, as he wants to do it by himself. He only wants to know whether it is possible or not.

Input
Each test case in the input le consists of two lines:
 The fi rst line contains a sequence of natural numbers. The first one (1<=n<=5) is the number of unknowns that will occur in the expression. It is followed by a sequence of n integers v1 … vn (0<=vi<=50), which are the values to be assigned to the unknowns. Finally, there is an integer m (0<=m<=1000) representing the desired result of the evaluation of the expression.
 The second line contains an arithmetic expression composed of lowercase letters (a-z), brackets (( and )) and binary operators (+, -, *). This expression will contain n unknowns, represented by n di fferent lowercase letters, without repetitions. The expression will not contain any blanks and will always be syntactically correct, i.e. it is just an unknown or has the form (e1 op e2 ), where e1 and e2 are expressions and op is one of the three possible binary operators.
The input will finish with a dummy test case of just one line containing 0 0, which must not be processed.

Output
For each test case, print a single line with YES if there exists an assignment of the values v1 … vn to the unknowns such that the expression evaluates to m, and NO otherwise. Notice that each value vi must be assigned to exactly one unknown.

Sample Input
3 2 3 4 14
((a+b)*c)

2 4 3 11
(a-b)

1 2 2
a

0 0

Sample Output
YES
NO
YES

题目链接:HDOJ-4192

题目大意:给出n个数字,ans和算式,问是否存在一组排列满足这个算式

题目思路:用栈实现计算器

以下是代码:

#include <iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<cstring>
#include<string>
#include<set>
#include<stack>
#include<map>
#include<queue>
#include<algorithm>

using namespace std;

stack <int> st;    //用于存储算式中的数字
stack <char> st2;   //用于存储算式中的符号
int v[10];    //存储数字
int poi[10];  //存储下标,用于next_permutation排列数字
int solve(int a,int b,char temp) 
{
    if (temp == '+') return a + b;
    else if (temp == '-') return a - b;
    else if (temp == '*')return a * b;
}

int comp(char a,char b){   //判断符号的优先级
    if(a=='+')
    {  
        if(b=='+' || b=='-' || b==')')return 1;  
        else return -1;  
    }  
    if(a=='-')
    {  
        if(b=='+' || b=='-' || b==')')return 1;  
        else return -1;  
    }  
    if(a=='*')       // '('优先级最大
    {    
        if(b=='(')return -1;  
        else return 1;  
    }  
    if(a=='(')    //左右括号匹配
    {      
       if(b==')')return 0;  
       else return -1;  
    }  
    if(a==')')   return 1;        //‘)’优先级最小
}
int main()
{
    int n;
    while(scanf("%d",&n) && n)
    {
        int temp = 0;
        int ok = 0;
        memset(v,0,sizeof(v));
        memset(poi,0,sizeof(poi));
        for (int i = 1; i <= n; i++)
        {
            scanf("%d",&v[i]);
            poi[i] = i;
        }
        int result;
        scanf("%d",&result);
        string s,t;
        cin >> t;
        s = "(" + t + ")";
        do
        {
            while(!st.empty())st.pop();
            while(!st2.empty())st2.pop();
            int k = 1;  
            st2.push('(');              //需要注意
            for (int i = 1; i < s.size(); i++)  
            {
                if (isalpha(s[i]))   st.push(v[poi[k++]]);   //如果是数字,压入数字的栈中
                else
                {
                    temp = comp(st2.top(),s[i]);      //判断符号优先级
                    if (temp == 1)           //如果栈顶符号优先级大,取出数字栈顶两个元素进行计算后压回栈顶
                    {
                        int a = st.top();    st.pop();
                        int b = st.top();    st.pop();
                        st.push(solve(b,a,st2.top()));
                        st2.pop();
                        i--;      //需要注意,
                    }
                    else if (temp == 0)   st2.pop(); //括号匹配
                    else if (temp == -1)  st2.push(s[i]);  //如果栈顶元素优先级较小,将当前元素压入栈顶
                }       
            }
            if (st.top() == result)
            {
                ok = 1;
                break;
            }
        }while(next_permutation(poi + 1,poi + n + 1));
        if (ok)  cout << "YES\n";
        else cout << "NO\n";
    }
    return 0;
}

你可能感兴趣的:(hdoj,4192)