noi1789:算24——搜索

本文介绍了一个用于解决算24问题的算法实现,该算法通过递归和组合运算符来组合四个正整数,以判断是否能形成等式等于24。通过实例演示了如何将四个数通过加、减、乘、除和括号操作得到24的解决方案,同时提供了源代码实现。
摘要由CSDN通过智能技术生成

1789:算24

View Submit Statistics Clarify
总Time Limit: 3000ms Memory Limit: 65536kB
Description
给出4个小于10个正整数,你可以使用加减乘除4种运算以及括号把这4个数连接起来得到一个表达式。现在的问题是,是否存在一种方式使得得到的表达式的结果等于24。


这里加减乘除以及括号的运算结果和运算的优先级跟我们平常的定义一致(这里的除法定义是实数除法)。


比如,对于5,5,5,1,我们知道5 * (5 – 1 / 5) = 24,因此可以得到24。又比如,对于1,1,4,2,我们怎么都不能得到24。
Input
输入数据包括多行,每行给出一组测试数据,包括4个小于10个正整数。最后一组测试数据中包括4个0,表示输入的结束,这组数据不用处理。
Output
对于每一组测试数据,输出一行,如果可以得到24,输出“YES”;否则,输出“NO”。
Sample Input
5 5 5 1
1 1 4 2
0 0 0 0
Sample Output
YES
NO

题目分析:这个题目扩展出状态好想,但如何表达不容易,首先考虑是记录每个数字,和另一个数字的关联运算,记录值,但不同的阶段的返回状态不好记录。

参考了别人的题解。处理的办法和八皇后很像,直接在数中中记录计算后的状态,然后又是模板算法了……

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>

using namespace std;
double a[4];
bool vis[4];
bool dfs(int step)
{
    int i,j;
    if(step == 4){   
        for(i = 0; i < 4; ++i)      
            if(!vis[i])          
                if(fabs(a[i] - 24) < 0.0001) return true;
        return false;
    }
    else{   
        for(i = 0; i < 4; ++i)      
            if(!vis[i])       
                for(j = i + 1; j < 4; ++j)              
                    if(!vis[j])
                    {
                        double tmpi = a[i];
                        double tmpj = a[j];
                        vis[j] = true;

                        a[i] = tmpi + tmpj;
                        if(dfs(step+1)) return true;//原来这里直接用了return dfs(step+1),当然是错的,找到了返回true,本次找不到不代表别的找不到啊。

                        a[i] = tmpi*tmpj;
                        if(dfs(step+1)) return true;

                        a[i] = tmpi-tmpj;
                        if(dfs(step+1)) return true;

                        a[i] = tmpj-tmpi;
                        if(dfs(step+1)) return true;

                        a[i] = tmpi/tmpj;
                        if(dfs(step+1)) return true;

                        a[i] = tmpj/tmpi;
                        if(dfs(step+1)) return true;

                        a[i] = tmpi;;
                        vis[j] = false;
                    }               
    }
    return false;
}


int main(){
    cin>>a[0]>>a[1]>>a[2]>>a[3];
    while(a[0]+a[1]+a[2]+a[3]>1){    
        memset(vis,0,sizeof(vis));
        if(dfs(1)) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
        cin>>a[0]>>a[1]>>a[2]>>a[3];
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值