算24——递归
来一题比较有难度的题目:这题同样是采用问题分解的办法,看看能不能得到一个递归式。
自己总结一遍就是一开始有n个数算24,往n个数里面取出来2个先进行计算,算出来的结果存到一个数组里面去,现在就变成 了n-1个数算24.这样很明显就发现了递归的关系了。
这里有一个注意点就是浮点数算相等的话不是使用 == 的是相减等于一个非常小的数。知道数组里面只有一个数的时候就可以退出递归了。
#include#include using namespace std; double a[5]; #define EPS 1e-6//这个就是那个很小的数 bool isZero (double x){ return fabs(x) <= EPS;//判断差的绝对值 } bool count24 (double a[],int n){ if( n == 1){//如果数组中只有一个数的时候退出递归 if(isZero(a[0]-24)){ return true; }else{ return false; } } duoble b[5];//用来储存除了少了前两个数 for(int i = 0;i 1;i++){//注意第一个数的循环不能找最后一个数,这个数一定是第二个数 for(int j = i+1;j ){ int m = 0;//m = n-2 for(int k = 0;k ){ if(k!=i&&k!=j){ b[m++] = a[k]; } }//这个数组里面储存除了第i个和第j个数之外的数
b[m] = a[i]+a[j];//把最开始枚举的数算出来 if(count24(b,m+1)){//然后就算前n-1个数如果是true的话就直接返回 //m+1其实就是n-1 return true; } b[m] = a[i]-a[j]; if(count24(b,m+1)){ //m+1其实就是n-1 return true; } b[m] = a[j]-a[i];//两个相减不同会导致不同的结果 if(count24(b,m+1)){ //m+1其实就是n-1 return true; } b[m] = a[i]*a[j]; if(count24(b,m+1)){ //m+1其实就是n-1 return true; } if(!isZero(a[j])){//这个地方要注意有两种情况可能会使除数为0 b[m] = a[i]/a[j]; if(count24(b,m+1)){ return true; } } if(!isZero(a[i])){ b[m] = a[j]/a[j]; if(count24(b,m+1)){ return true; } } } } return false; } int main(){ while(true){ for(int i = 0;i<4;i++){ cin>>a[i]; } if(isZero(a[0])) break; if(count24(a,4)){ cout<<"yes"<<endl; }else<<"no"<<endl; } } return 0; }
这个程序如果我自己写的话很难写出来,我感觉技术含量还是很高啊,首先这种表达式只要有涉及到除法的话,无论怎么样都是要有double型的变量的。还有要判断特殊情况。要自己仔细看看从这个程序里面可以学到什么。