GOJ 1454 计算24点

思路:算24点可以归结为 A B C D=24(中间添加运算符以及括号)。一共4个数,对其进行全排列4!=24种,然后对于每一种排列添加运算符和括号。判断结果是否等于24.

这种题目是思路很简单,但是实践起来却很考研编程技巧以及思维上的取巧。

首先要引入一个以前从未接触过的函数:next_permutation。(全排列函数,用之前一定要sort一下,因为它只输出当前这种排列后的排列)

范例:

第一个输出结果第一列都为1,下面分别是1 2 3中缺失的。具体可以百度一下。

然后就是小技巧了:对于+和*来说它们满足交换律,但对于-和/来说则不满足,因此,这里定义一个(~/)和(~-)的概念,这样就有a-b=b~-a,于是乎所有操作都满足交换律。即所有的括号添加就只有这两种情况:(((a#b)#c)#d)和(a#b)#(c#d)这里的"#"表示任意运算。其他的添加括号的方式都可以通过交换律转化成这两种。

具体参考:http://blog.csdn.net/octopusflying/article/details/51428337。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,a[4];
double eps=1e-6;///因为用到double所以注意精度的设置

double cal(double a,double b,int op){///注意传值传double
    if(op==0)
        return (a+b)*1.0;
    else if(op==1)
        return (a-b)*1.0;
    else if(op==2)
        return (b-a)*1.0;
    else if(op==3)
        return a*b*1.0;
    else if(op==4&&b!=0)
        return (1.0*a)/b;
    else if(op==5&&a!=0)
        return (1.0*b)/a;
}

void solve(){
    do{
        for(int i=0;i<6;i++)
            for(int j=0;j<6;j++)
             for(int k=0;k<6;k++){
             if(abs(cal(cal(cal(a[0],a[1],i),a[2],j),a[3],k)-24)<eps)///((a$b) $c)$d
             {printf("YES\n");return;}
             if(abs(cal(cal(a[0],a[1],i),cal(a[2],a[3],k),j)-24)<eps)///(a$b)$(c$d)
             {printf("YES\n");return;}
            }
    }while(next_permutation(a,a+4));
    printf("NO\n");
    return;
}

int main(){
    while(scanf("%d",&n)!=EOF){
        for(int i=0;i<n;i++){
            for(int j=0;j<4;j++)
                scanf("%d",&a[j]);
        sort(a,a+4);
        solve();
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值