算24
这道题的dfs:
a b c d
这四个数
每次从中拿两个做+/-/*/÷ 这样就可以不考虑超级麻烦的括号问题,
举例a和b,有a+b,a-b,b-a,a*b,a/b,b/a 六种计算,a和b计算结果再和c,再和d进行计算,最后判断是否等于24.
具体实现:
1.建立i外循环 i:1~n;和内循环 j:i+1~n;
2.建立vis数组判断i,j是否被计算过,如果 vis[i] 或者vis[j] 有一个被==1,被用过,则coutinue进入下一个,i,j。
3.a[i]赋值于pre
pre和a[j]进行6中计算,除法计算需要判断除数不为零,具体用是否大于eps进行判断
计算结果存入a[i]中,
4. 递归dfs(cnt-1)
5.vis[j]=0,a[i]=pre;恢复递归前状态
6.出递归条件,cnt==1,如果a[1]和24的差小于eps,则修改flag=1。。 返回函数。
小细节说明
1、对输入的处理:
while(1) { fg=0;//状态用于 cout YES OR NOint sum=0;//和,用来判断是不是结束了 for(int i=1;i<=n;i++) { scanf("%lf",&a[i]);//a[i]一定要用 double 因为后面有除法 sum+=a[i]; } if(sum==0) break;//如果结束了退出 dfs(4);//dfs函数 if(fg==1) printf("YES\n");//输出结果 else printf("NO\n"); }
2.函数的退出条件
if(cnt==1)//如果只剩一个数了 { if(fabs(a[1]-24)<eps)//判断a[1]是否等于24 一般a-b误差小于1e-6则认为a==b { fg=1;//将fg改为是 }//没有else return; }
代码:
#include<bits/stdc++.h> using namespace std; double a[10]; int n,fg; double eps=1e-6; int vis[10]={0}; void dfs(int cnt) { if(cnt==1) { if(fabs(a[1]-24)<eps) { fg=1; } return; } else { for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { double pre=a[i]; if(vis[i]==1||vis[j]==1) continue; a[i]=pre+a[j]; vis[j]=1; dfs(cnt-1); a[i]=a[j]-pre; dfs(cnt-1); a[i]=pre-a[j]; dfs(cnt-1); a[i]=pre*a[j]; dfs(cnt-1); if(fabs(pre)>eps) { a[i]=a[j]/pre; dfs(cnt-1); } if(fabs(a[j])>eps) { a[i]=pre/a[j]; dfs(cnt-1); } a[i]=pre,vis[j]=0; } } } } int main() { while(1) { fg=0; n=4; int sum=0; for(int i=1;i<=n;i++) { scanf("%lf",&a[i]); sum+=a[i]; } if(sum==0) break; dfs(4); if(fg==1) printf("YES\n"); else printf("NO\n"); } return 0; }