openjudge-NOI 2.5-1789 算24
题目链接:http://noi.openjudge.cn/ch0205/1789/
题解:
并不是非常简单的搜索,需要考虑一些东西……
首先有运算符优先级的限制,还有括号,数字的顺序也可以调整,如果只是简单给式子添加运算符和括号,会比较难生成,生成后计算或许还要转换成后缀表达式之类的,很麻烦……
可以将四个数字添加进一个集合(但并不满足互异性),每次从中提取出两个数字分别进行四种计算,将结果放回集合,如此往复直到只剩一个数字,再与24比较即可(注意不一定非要相等,在适当精度内就可以)
这样也不需要考虑优先级之类的,也可以枚举出所有情况
曾经想练一下用滚动数组写一下,因为没法解决回溯问题就失败了……
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 using namespace std; 5 double a[5][5]; 6 bool dfs(int dep) 7 { 8 if(dep==4) 9 { 10 if(abs(a[dep][1]-24.0)<=0.01)return true; 11 return false; 12 } 13 int n=4-dep+1; 14 double t1,t2; 15 for(int i=1;i<=n;++i) 16 { 17 for(int j=1;j<=n;++j) 18 { 19 if(i==j)continue; 20 t1=a[dep][i]; 21 a[dep][i]=0; 22 t2=a[dep][j]; 23 a[dep][j]=0; 24 int m=1; 25 for(int l=2;l<=n-1;++l) 26 { 27 while(!a[dep][m])++m; 28 a[dep+1][l]=a[dep][m]; 29 ++m; 30 } 31 a[dep+1][1]=t1+t2; 32 if(dfs(dep+1))return true; 33 a[dep+1][1]=t1-t2; 34 if(dfs(dep+1))return true; 35 a[dep+1][1]=t1*t2; 36 if(dfs(dep+1))return true; 37 a[dep+1][1]=t1/t2; 38 if(dfs(dep+1))return true; 39 a[dep][i]=t1; 40 a[dep][j]=t2; 41 } 42 } 43 return false; 44 } 45 int main() 46 { 47 while(1) 48 { 49 memset(a,0,sizeof(a)); 50 scanf("%lf %lf %lf %lf",&a[1][1],&a[1][2],&a[1][3],&a[1][4]); 51 if(!a[1][1])break; 52 if(dfs(1))printf("YES\n"); 53 else printf("NO\n"); 54 } 55 return 0; 56 }