递归例题:算24

2017-11-02  本文已影响0人  见习炼丹师
#include <iostream>
#include <cmath>
#define EPS 1e-6

using namespace std;

double arr[5];

bool isZero(double n){
    if(fabs(n-0)<EPS)
        return true;
    return false;
}

//参数的意思是输入的数字和数字的个数
bool canfind(double a[],int n){
    if(n==1){
        if(isZero(a[0]-24)){
            return true;
        }
        else
            return false;
    }
    double b[5];
    //通过两重循环来遍历所有的取两个数字的情况
    for(int i=0;i<n;++i){
        for(int j=i+1;j<n;++j){
            int m=0;
            //先给n-2的数字赋上值
            for(int k=0;k<n;++k){
                if(k!=j&&k!=i){
                    b[m++]=a[k];
                }
            }
            //开始枚举这两个数字的运算方式,如果
            b[m]=a[i]+a[j];
            if(canfind(b,n-1)){
                return true;
            }
            b[m]=a[i]-a[j];
            if(canfind(b,n-1)){
                return true;
            }
            b[m]=a[j]-a[i];
            if(canfind(b,n-1))
                return true;
            b[m]=a[i]*a[j];
            if(canfind(b,n-1))
                return true;
            if(!isZero(a[i])){
                b[m]=a[j]/a[i];
                if(canfind(b,n-1))
                    return true;
            }
            if(!isZero(a[j])){
                b[m]=a[i]/a[j];
                if(canfind(b,n-1))
                    return true;

            }
    }

    }
    return false;
}

int main()
{
    while(true){
        for(int i=0;i<4;++i){
            cin>>arr[i];
        }
        if(isZero(arr[0]))
            break;
        if(canfind(arr,4))
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;
    }
    return 0;
}

这道题相对复杂,是属于可以先走一步不断递归降低问题规模的类型,总体思想是不断地将两个数字通过枚举所有的四种运算方法变成一个数字,这样n个数的问题就转化为了n-1个,直到问题简化伪为1个数字是否为24。同时注意代码实现时不要将double=0,注意细节比如除数不能等于0。先行写出边界条件。

上一篇下一篇

猜你喜欢

热点阅读