题目在这里》
题意:给你一个中序表达式,由(、)、+、-、*以及a-z的小写字母组成,其中有n个不同的小写字母表示n个未知数,再给n个数分别表示这n个未知数的值,再给一个数m,求判断是否能够将这n个数分别赋值给这n个未知数代入表达式所算出的值恰为m。
思路:由于题目给的是中序表达式,不方便计算,所以要先将中序表达式转化为逆波兰式。
先来复习一下将一个中序表达式转化为逆波兰式的算法:
1:准备2个栈,一个存符号(记为栈1),另一个存变量(记为栈2);
2:依次读取中序表达式,
(1)如果当前字符是‘(’,直接进栈1;
(2)如果当前字符是‘)’,将符号栈栈顶元素依次弹入栈2,直至符号栈栈顶为‘(’,此时‘(’出栈;
(3)如果是变量,直接进栈2;
(4)如果是运算符
1》如果符号栈栈顶运算符优先级小于当前运算符优先级,或者符号栈为空或者符号栈栈顶元素为‘(’,直接进栈;
2》如果符号栈栈顶运算符优先级大于等于当前运算符优先级,将符号栈栈顶元素依次弹入栈2,直到符号栈栈顶运算符优先级小于当前运算符优先级,当前运算符进栈1;
好了,将中序表达式转化为逆波兰式后就好办了,直接求n个数的全排列,然后用逆波兰式轻松求出表达式的值就简单多了,详情请见代码:
#include <iostream> #include<cstdio> #include<cstring> using namespace std; char stack1[20],stack2[20],str[20]; int top1,top2; int n,m; int v[10]; int flag; int fv[10]; int cur[10]; int cal() { int i,j; int lcm[10],len = 0; j = 0; for(i = 0;i < top2;i ++) { if(islower(stack2[i])) lcm[len ++] = cur[j ++]; else { len --; switch(stack2[i]) { case '+':lcm[len - 1] += lcm[len]; break; case '-':lcm[len - 1] -= lcm[len]; break; case '*':lcm[len - 1] *= lcm[len]; } } } return lcm[0]; } void dfs(int i,int cnt) { if(flag) return; if(cnt == n - 1) { if(cal() == m) { flag = 1; } return; } int j; for(j = 0;j < n;j ++) { if(!fv[j]) { fv[j] = 1; cur[cnt + 1] = v[j]; dfs(j,cnt + 1); fv[j] = 0; } } } int main() { int i; char c; while(scanf("%d",&n),n) { for(i = 0;i < n;i ++) scanf("%d",&v[i]); scanf("%d",&m); top1 = top2 = 0; scanf("%s",str); for(i = 0;i < strlen(str);i ++) { switch(str[i]) { case '(':stack1[top1 ++] = str[i]; break; case ')':while(stack1[top1 - 1] != '(') stack2[top2 ++] = stack1[--top1]; top1 --; break; case '*':if(top1 == 0 || stack1[top1 - 1] == '+' || stack1[top1 - 1] == '-' || stack1[top1 - 1] == '(') stack1[top1 ++] = '*'; else { while(stack1[top1 - 1] == '*') stack2[top2 ++] = stack1[--top1]; } break; case '+': case '-':if(stack1[top1 - 1] == '(' || top1 == 0) stack1[top1 ++] = str[i]; else { while(stack1[top1 - 1] == '*')//stack1[top1 - 1] == '+' || stack1[top1 - 1] == '-')//之前写的有问题,竟然能过。。。 stack2[top2 ++] = stack1[--top1]; } break; default:stack2[top2 ++] = str[i]; } } flag = 0; for(i = 0;i < n;i ++) { memset(fv,0,sizeof(fv)); fv[i] = 1; cur[0] = v[i]; dfs(i,0); } if(flag) printf("YES\n"); else printf("NO\n"); /*for(i = 0;i < top2;i ++) printf("%c",stack2[i]); printf("\n");*/ } return 0; } //62MS 324K