题意:给你一个中序表达式,由(、)、+、-、*以及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