看到题目,想到除了dfs枚举之外没有什么好方法了,但是最初我以为不需要判重,所以TLE,仔细想想,应该写一个vis[110][64000]的数组判重的,在cur时如果曾出现过sum的值,这个就不必再进行下去了。(这个题中的vis数组这一部分自己做的不好)。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int target,p,num[110],ans,vis[110][640005];
char ch[110];
void dfs(int cur,int sum)
{
if(sum>32000||sum<-32000) return ;
if(cur==p&&sum==target)
{
ans=1;
return ;
}
if(cur>=p) return ;
int nn=sum;
nn/=num[cur];
ch[cur]='/';
if(nn>=-32000&&nn<=32000&&!vis[cur][nn])
{
vis[cur][nn]=1;
dfs(cur+1,nn);
}
if(ans==1) return ;
sum-=num[cur];
ch[cur]='-';
if(sum>=-32000&&sum<=32000&&!vis[cur][sum])
{
vis[cur][sum]=1;
dfs(cur+1,sum);
}
if(ans==1) return ;
sum+=num[cur];
sum+=num[cur];
ch[cur]='+';
if(sum>=-32000&&sum<=32000&&!vis[cur][sum])
{
vis[cur][sum]=1;
dfs(cur+1,sum);
}
if(ans==1) return ;
sum-=num[cur];
sum*=num[cur];
ch[cur]='*';
if(sum>=-32000&&sum<=32000&&!vis[cur][sum])
{
vis[cur][sum]=1;
dfs(cur+1,sum);
}
if(ans==1) return ;
sum/=num[cur];
}
int main()
{
//freopen("in.txt","r",stdin);
int cas;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&p);
for(int i=0; i<p; i++)
scanf("%d",&num[i]);
scanf("%d",&target);
ans=0;
memset(vis,0,sizeof(vis));
dfs(1,num[0]);
if(ans==0)
cout<<"NO EXPRESSION\n";
else
{
cout<<num[0];
for(int i=1; i<p; i++)
cout<<ch[i]<<num[i];
cout<<"="<<target<<endl;
}
}
return 0;
}