第一次直接搜,20s的时限T了,没看题目说明。。。。。看了看别人的代码找到了一个很有效的剪枝。。。。1.835s过了。。。
legal函数是剪枝。
/********************** * author:crazy_石头 * Pro:Problem H Game Show Math * algorithm:dfs * Time:1.835s * Judge Status:Accepted ***********************/ #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <set> #include <vector> using namespace std; #define rep(i,h,n) for(int i=(h);i<=(n);i++) const int maxn=100+5; bool ok; int n,ret; int a[maxn]; bool vis[maxn][32000<<1+5]; string ans; inline bool legal(int x, int y) { if (y>=-32000&&y<=32000&&!vis[x][y+32000]) { vis[x][y+32000]=true; return true; } return false; } inline void dfs(int cur,int num,string s)//cur是搜到的层数,num存储当前计算结果,s为运算符 { if(ok) return; if(cur==n) { if(num==ret) { ok=1; rep(i,0,n-2) { printf("%d%c",a[i],s[i]); } printf("%d=%d\n",a[n-1],ret); } return ; } else { if(legal(cur+1,num+a[cur+1])) dfs(cur+1,num+a[cur+1],s+'+'); if(legal(cur+1,num-a[cur+1])) dfs(cur+1,num-a[cur+1],s+'-'); if(legal(cur+1,num*a[cur+1])) dfs(cur+1,num*a[cur+1],s+'*'); if(a[cur+1]!=0&&num%a[cur+1]==0&&legal(cur+1,num/a[cur+1])) dfs(cur+1,num/a[cur+1],s+'/'); } } int main() { int test; scanf("%d",&test); while(test--) { memset(a,0,sizeof(a)); memset(vis,0,sizeof(vis)); scanf("%d",&n); rep(i,0,n-1) scanf("%d",&a[i]); scanf("%d",&ret); ok=0; dfs(0,a[0],ans); if(!ok) printf("NO EXPRESSION\n"); } return 0; } |
* This source code was highlighted by YcdoiT. ( style: Desert )