#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int vis[4];
double num[4];
const double delta=1e-5;
bool zero(double x){
return x>-delta&&x<delta;
}
int n;
bool dfs(){
if(n==1){
for(int i=0;i<4;++i) if(!vis[i]&&zero(num[i]-24)) return 1;
return 0;
}
for(int i=0;i<4;++i){
for(int j=i+1;j<4;++j){
--n;
if(!vis[i]&&!vis[j]){
vis[j]=1;
double tmp=num[i],x=num[i],y=num[j];
num[i]=x+y;if(dfs()) return 1;
num[i]=x-y;if(dfs()) return 1;
num[i]=y-x;if(dfs()) return 1;
num[i]=x*y;if(dfs()) return 1;
if(!zero(x))num[i]=y/x;if(dfs()) return 1;
if(!zero(y)) num[i]=x/y;if(dfs()) return 1;
num[i]=tmp;vis[j]=0;
}
++n;
}
}
return 0;
}
int main(){
while(scanf("%lf%lf%lf%lf",&num[0],&num[1],&num[2],&num[3])==4&&!(num[0]==0&&num[1]==0&&num[2]==0&&num[3]==0)){
n=4;
memset(vis,0,sizeof(vis));
if(dfs()) printf("YES\n"); else printf("NO\n");
}
}
很多坑,感谢舍友想哥帮我揪出bug,不然我可能会浪费很多时间!
然而在实现的过程中还是遇到了很多问题
double判等一定要自定义一个delta和zero函数
version1我刚才想反其道而行之,逆过来算,即从24点出发,将最后一个操作数挪过来,得到一个由三个数计算得到一个新的结果的问题,但其实是不对的。因为有些24点只能由(5-2)*(6+2)这种形式计算。
versrion2任选两个数,计算其加减乘除的结果,替换原来的两个数,直到数的个数为1,此时只需判断是否为24。