题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4192
题目的意思就是先给出n个数据,在给出一个结果m,在给你一个含有n个变量的表达式,问是否存在一种方式将数据一一代入变量,使得表达式的结果等于m。
解题思路:由于n不大,所以可以暴力求出这n个数的所有组合方式,然后求出结果看是不是等于m,得到组合后就可以替换变量得到一个不含未知数的中缀表达式,就可求出结果,这题用了以前的先建树在求解的模板,一直超时,后来改了,直接以建树的方式求解,就过了,参考代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define MAX 105
#define CLR(arr) memset(arr,0,sizeof(arr))
char str[MAX]; //中序表达式
int num[10],vis[10],res[10]; /*num[]存入初始数据,res[]存入组合方式(存的是下标),*/
char strr[MAX],str1[MAX],ch[10],s[10][10];
/*strr数组转化后的表达式,str1含未知数的表达式,s为给出的几个数据用字符串存起来*/
int creat(int b,int e)
{
if(b > e) return 0;
int p = -1,cnt = 0,flag = 0;
for(int i = b;i <= e;++i)
{
if(str[i] == '(') cnt++;
else if(str[i] == ')') cnt--;
else if((str[i] == '+' || str[i] == '-') && !cnt){flag = 1; p = i;}
else if((str[i] == '*' || str[i] == '/') && !cnt && !flag) p = i;
}
if(p == -1)
{
if(str[b] <= '9' && str[b] >= '0')
{
int res = 0; int n = 0;
sscanf(&str[b],"%d%n",&res,&n);
return res;
}
return creat(b+1,e-1);
}
else
{
switch(str[p])
{
case '+':return creat(b,p - 1) + creat(p + 1,e);
case '-':return creat(b,p - 1) - creat(p + 1,e);
case '*':return creat(b,p - 1) * creat(p + 1,e);
default: break;
}
}
}
int EXP(char st[])
{
strcpy(str,st);
return creat(0,strlen(str)-1); //中序求出结果
}
bool dfs(int p,int n,int m) //深搜考虑每一种情况
{
if(p == n)
{
CLR(strr);
int pos = 0;
for(int i = 0;i < strlen(str1);++i)
{
if(str1[i] <= 'z' && str1[i] >= 'a')
strcat(strr,s[ res[pos++] ]);
else
{
ch[0] = str1[i];
ch[1] = '\0';
strcat(strr,ch);
}
}
int a = EXP(strr);
if(a == m) return true;
else return false;
}
for(int i = 0;i < n;++i)
{
if(!vis[i])
{
vis[i] = true;
res[p] = i;
if(dfs(p+1,n,m)) return true;
vis[i] = false;
}
}
return false;
}
int main()
{
int m,n;
char cha[10];
while(~scanf("%d",&n))
{
if(!n) return 0;
CLR(str1); CLR(res);
CLR(num); CLR(vis);
int pos,r;
for(int i = 0;i < n;++i)
{
scanf("%d",&num[i]);
CLR(ch); CLR(cha);
pos = 0;
r = num[i];
/****数字转换为字符串*****/
if(!r) cha[pos++] = '0';
while(r)
{
cha[pos++] = '0' + (r % 10);
r /= 10;
}
for(int j = 0;j < pos;++j)
ch[j] = cha[pos-1-j];
ch[pos] = '\0';
strcpy(s[i],ch);
/*****************/
}
scanf("%d",&m);
scanf("%s",str1);
if(dfs(0,n,m)) printf("YES\n");
else printf("NO\n");
}
return 0;
}