算24(深搜)

算24
总时间限制: 3000ms 内存限制: 65536kB
描述
给出4个小于10个正整数,你可以使用加减乘除4种运算以及括号把这4个数连接起来得到一个表达式。现在的问题是,是否存在一种方式使得得到的表达式的结果等于24。
这里加减乘除以及括号的运算结果和运算的优先级跟我们平常的定义一致(这里的除法定义是实数除法)。
比如,对于5,5,5,1,我们知道5 * (5 – 1 / 5) = 24,因此可以得到24。又比如,对于1,1,4,2,我们怎么都不能得到24。
输入
输入数据包括多行,每行给出一组测试数据,包括4个小于10个正整数。最后一组测试数据中包括4个0,表示输入的结束,这组数据不用处理。
输出
对于每一组测试数据,输出一行,如果可以得到24,输出“YES”;否则,输出“NO”。
样例输入

5 5 5 1
1 1 4 2
0 0 0 0

样例输出


YES
NO

思路点拔:对于每两个数,有八种状态:a+b,b+a,a*b,b*a,a-b,b-a,a/b,b/a;但你可以发现,不用把8状态全部列举出来,因为a+b与b+a相等,a*b与b*a相等,所以对这6种情况进行搜索即可,上代码!!!!

#include
#include
#include
#include
using namespace std;
double a[5];
bool f[5];
bool dfs(int x)
{
    if(x==4) //如果4个数都算了
    {
        for(int i=1;i<=4;i++)
        //注意:这里存在一个精度问题,因为在算24时会存在小数
           if(!f[i]&&fabs(a[i]-24.0)<0.000001) 
              return true;
        return false;
   }
     for(int i=1;i<=4;i++) //搜索四个数
    {
       if(!f[i]) //判断四个数有没有算过
       {
         for(int j=i+1;j<=4;j++)
            if(!f[j])
            {
                f[j]=true;
                double t1=a[i],t2=a[j];
                a[i]=t1+t2; //a+b的情况
                if(dfs(x+1))  //继续递归计算下一个组合
                {
                    return true;
                }
                a[i]=t1-t2;//a-b的情况
                if(dfs(x+1)) //继续递归计算下一个组合
                {
                    return true;
                }
                a[i]=t2-t1;//b-a的情况
                if(dfs(x+1)) //继续递归计算下一个组合
                {
                    return true;
                }
                a[i]=t1*t2; //a*b的情况
                if(dfs(x+1)) //继续递归计算下一个组合
                {
                    return true;
                }
                a[i]=t1/t2; //a/b的情况
                if(dfs(x+1)) //继续递归计算下一个组合
                {
                    return true;
                }
                a[i]=t2/t1; //b/a的情况
                if(dfs(x+1)) //继续递归计算下一个组合
                {
                    return true;
                }
                a[i]=t1; //回溯
                f[j]=false;
            }
        }
    }
    return false; 
}
int main()
{
    while(1) //无限输入
    {
        int k=0;
        memset(f,0,sizeof(f));//清空数组
        for(int i=1;i<=4;i++)
        {
            scanf("%lf",&a[i]);
            if(a[i]!=0) k=1;
        }
        if(k==0) //遇到0就结束
        {
            return 0;
        }
        if(dfs(1)==1) //搜索,如果算出了24,就输出YES
        {
            printf("YES\n");
        }
        else       //否则就输出NO
        {
            printf("NO\n");
        }          
    }
    return 0;//结束啦!!
}

//还是经典深搜,再多多跟着代码走走,推推^_^

你可能感兴趣的:(搜索)