题目描述:
     给定4个数字,判定这4个数字是否可以通过运算得到结果24。运算操作包括:加、减、乘、除,允许变换数字的顺序,允许使用括号改变运算顺序。
    即:判定是否存在一种通过在下面的圆圈中添加运算符以及添加括号的方式使得等式成立:
            a ○ b ○ c ○ d = 24
    例:数字 5, 5, 5, 1 可以通过运算得到结果24: 
            5 × (5 - 1 ÷ 5) = 24
        数字 9, 9, 9, 9 则无论通过怎样的运算都无法得到24的结果。

解答:
    本题还是比较简单的,由于数据量比较少,因此可以采用暴力搜索的方式进行解答,枚举所有的可能的运算方式,如果有1种方案可以达到24,则表明给定的数据有解,否则无解。
    枚举的方式如下:
    由于加法和乘法满足交换律,而减法和出发则不满足,这里我们添加两种运算:“反减”和“反除”,分别记作 ~- 和 ~÷,此时:
                        a ~-  b = b -  a
                        a ~÷ b = b ÷ a
    添加这两种运算操作后,就使得减法和除法也同样符合交换律。此时,所有情况的运算顺序就只有两种情况,用※表示任意的运算符,则两种运算顺序为:
        ((a  ※ b) ※ c)  ※ d))          <从左到右依次计算>
        ((a  ※ b) ※ (c  ※ d))          <分别计算前两个和后两个数字的结果后,在将得到的两个结果进行运算,得到最终的结果>

而其他的运算顺序均可以通过调整数字的排列顺序得到用以上两种情况表示的等价情况,例如:
        (a  ※ ((b ※ c)  ※ d))    =====>  ( ((b  ※ c)  ※ d)   ※ a)  
         ((a ※ (b ※ c))  ※ d)    =====>  (( (b  ※ c)  ※ a)  ※ d)
    这样,通过枚举4个数字排列情况和三个位置的运算符的不同情况,就可以枚举到所有的运算情况。其中:4个数字排列,共有4!= 24种结果,而3个运算符中每个运算符都有6种不同的情况,因此共有6^3 = 216中情况,而运算顺序又有2中情况,因此,总的情况数为:
                            24 × 216 × 2 = 10368
    由于加法和乘法本身就具有交换律,并且给定的4个数字也有某些数字相同的情况,因此,在实际枚举过程中,10368种情况会有某些是重复的。本题数据量比较小,因此重复计算的问题可以忽略。

输入输出格式:
    输入: 第1行:1个正整数, t,表示数据组数;第2..t+1行:4个正整数, a,b,c,d。
    输出:对每组测试数据输出一行,表明能 否计算出24点。若能够输出"Yes",否则输出"No"。

数据范围:
      2 ≤ t ≤ 100
      1 ≤ a,b,c,d ≤10

程序代码:

/****************************************************/
/* File        : Hiho_Week_98                       */
/* Author      : Zhang Yufei                        */
/* Date        : 2016-05-16                         */
/* Description : HihoCoder ACM program. (submit:g++)*/
/****************************************************/#include<stdio.h>
#define DATA_TYPE float
#define INPUT_PATTERN "%f"// Record the input data.
DATA_TYPE data[4];/* Record the operator:*  0: Add      1: Substract    *  2: Multiply 3: Devide*  4: Reserve_Substract*    5: Reserve_Devide.*/
int op_value;// Record if the current calculate is legal.
int tag;/** This function computes the result according to given* data and operator.* Parameters:*      @a & @b: The data to compute.*        @op: The operator.* Returns:*      The result according to given data and operator,*       if the equation is illegal, returns -1.*/
DATA_TYPE compute(DATA_TYPE a, DATA_TYPE b, int op) {switch(op) {case 0: return a + b; break;case 1: return a - b; break;case 2: return a * b; break;case 3: if(b == 0) {tag = 0;return -1;} else {return a / b;}break;case 4: return b - a;case 5: if(a == 0) {tag = 0;return -1;} else {return b / a;}break;}
}/** This function checks if the data can get result 24.* Parameters:*      @index: The current index.* Returns:*      If the data can get result 24, returns 1,*      or returns 0.*/
int check(int index) {if(index == 4) {for(op_value = 0; op_value < 216; op_value++) {int op1 = op_value % 6;int op2 = op_value / 6 % 6;int op3 = op_value / 36;tag = 1;if(compute(compute(compute(data[0], data[1], op1), data[2], op2),data[3], op3) == 24 && tag) {return 1;}tag = 1;if(compute(compute(data[0], data[1], op1), compute(data[2], data[3], op3), op2) == 24 && tag) {return 1;}}return 0;}for(int i = index; i < 4; i++) {DATA_TYPE swap = data[index];data[index] = data[i];data[i] = swap;if(check(index + 1)) {return 1;}swap = data[index];data[index] = data[i];data[i] = swap;}return 0;
}/** This function deals with one test case.* Parameters:*      None.* Returns:*        None.*/
void function(void) {for(int i = 0; i < 4; i++) {scanf(INPUT_PATTERN, &data[i]);}if(check(0)) {printf("Yes\n");} else {printf("No\n");}
}/** The main program.*/
int main(void) {int t;scanf("%d", &t);for(int i = 0; i < t; i++) {function();}return 0;
}

ACM:搜索算法专题(1)——24点相关推荐

  1. [转载]ACM搜索算法总结(总结)

    原文地址:ACM搜索算法总结(总结)作者:GreenHand 搜索是ACM竞赛中的常见算法,本文的主要内容就是分析它的 特点,以及在实际问题中如何合理的选择搜索方法,提高效率.文章的第一部分首先分析了 ...

  2. ACM数论专题3——素数(质数)

    ACM数论专题3--素数 素数是什么 蛮力算法求素数 蛮力算法的实现以及分析 时间复杂度 蛮力算法的改进 时间复杂度 **埃筛** 时间复杂度 线筛 线筛原理分析 线筛实现 素数是什么 质数1 (pr ...

  3. 红客团队html引导,HTML语言--百度红客吧系列专题课程--24

    作者:三月十三 第24节.在表单中使用图形化按钮.单选按钮和复选按钮 上节课我们说的是,在表单中使用单行文本框以及密码框.提交按钮.重置按钮等,今天我们来学习一下使用图形化按钮和单选按钮和复选按钮. ...

  4. ACM 博弈专题(5种模板)

    最近算法课在学博弈论的知识,顺手把算法题中的涉及到博弈论一并总结了 这篇文章的有些内容是参考了大佬的 可能有遗漏.... (一)巴什博弈(BAsh Game) 题目模板 只有一堆n个物品 两个人轮流取 ...

  5. 鲜果网热点改版,增加热点专题

    涂雅导读: 最近鲜果的在线阅读器常常出现一些问题,比如是更新不及时,主要的原因是鲜果正在改版,只有在会员登录之后才会出现新片的热点,看一下新版和旧版有什么区别吧. 全文: 常用鲜果阅读器的细心用户可能 ...

  6. 网内计算:可编程数据平面和技术特定应用综述

    网内计算:可编程数据平面和技术特定应用综述 摘要--与云计算相比,边缘计算提供了更靠近终端设备的处理,降低了用户体验的延迟.最新的In-Network Computing范例采用可编程网络元素在数据达 ...

  7. 中科大提出统一输入过滤框架InFi:首次理论分析可过滤性,支持全数据模态

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 来自:机器之心 针对模型推理过程中的输入冗余,中科大新研究首次从理论角度进行了可过滤性 ...

  8. 国际会议排名zz(通信、网络类)

    原文:http://hi.baidu.com/jianfengguan/blog/item/7fdb3ac56e856bc238db4944.html Communication/Networking ...

  9. solr创建索引_Solr:创建拼写检查器

    solr创建索引 在上一篇文章中,我谈到了Solr Spellchecker的工作原理,然后向您展示了其性能的一些测试结果. 现在,我们将看到另一种拼写检查方法. 与其他方法一样,此方法使用两步过程. ...

最新文章

  1. VirtualBox的四种网络连接方式
  2. pycharm 远程调试
  3. 【Android 逆向】ART 脱壳 ( InMemoryDexClassLoader 脱壳 | DexFile 构造函数及相关调用函数 | Android 源码中查找 native 函数 )
  4. 对B样条的理解和整理
  5. 用python画出简单笑脸画法_【Python】怎么用matplotlib画出漂亮的分析图表
  6. 使用Custom.pll修改标准Form的LOV
  7. 2017 省赛选拨 想打架吗?算我一个!所有人,都过来!(3) 递推 斐波拉数列的应用...
  8. 树状数组的建树 单点修改 单点查询 区间修改 区间查询
  9. vue 一个页面有点请求需要同时发送_前端性能优化,这些你都需要知道
  10. 怎样用shell计算linux内存,计算Linux内存,CUP,硬盘使用率的shell脚本
  11. sql server 锁与事务拨云见日(下)
  12. JavaScript学习(七十一)—call、apply、bind学习总结
  13. 笔记本电池不充电了 无法充电 如何激活
  14. 物流供应链信息服务平台
  15. 贪心算法的数学证明 (更新中)
  16. 根据电压判断NPN和PNP管型
  17. 为什么要隐藏ip地址
  18. 云计算现在前景如何?怎么转型成为云计算工程师?
  19. 客户旅行地图教程 - 带15个示例
  20. R语言文字云神器wordcloud2包

热门文章

  1. ESP8266+OLED屏实现天气预报+温度显示+NTP时间同步6屏带中文显示版本迭代持续更新
  2. 加盐密码哈希:如何正确使用 (转)
  3. 小鹏汽车领投 这家车规级MEMS激光雷达公司完成数亿元Pre-C轮融资
  4. 300etf期权怎么玩?正规平台有哪些呢?
  5. edup无线网卡驱动安装linux,EDUP EP-N8513 (RTL8188CUS芯片)在Ubuntu 12.10下的wifi不能连接问题解决方法...
  6. mac调整启动台图标
  7. 管理每日日程提醒以及待办清单的备忘便签有哪些
  8. linux挂载windows共享目录报错,linux通过cifs挂载windows共享目录
  9. Python操作*.cfg配置文件
  10. 【数据结构与算法】LeetCode面试真题,带你领略算法思想