HDU 1427 速算24点 (深搜)
Problem Description
速算24点相信绝大多数人都玩过。就是随机给你四张牌,包括A(1),2,3,4,5,6,7,8,9,10,J(11),Q(12),K(13)。要求只用'+','-','*','/'运算符以及括号改变运算顺序,使得最终运算结果为24(每个数必须且仅能用一次)。游戏很简单,但遇到无解的情况往往让人很郁闷。你的任务就是针对每一组随机产生的四张牌,判断是否有解。我们另外规定,整个计算过程中都不能出现小数。
Input
每组输入数据占一行,给定四张牌。
Output
每一组输入数据对应一行输出。如果有解则输出"Yes",无解则输出"No"。
Sample Input
A 2 3 6
3 3 8 8
Sample Output
Yes
No
题目描述:
给定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种情况会有某些是重复的。本题数据量比较小,因此重复计算的问题可以忽略。
代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
using namespace std;
int num[4];
bool flag;
void dfs(int sum,int now,int times)
{
if(!flag)
return ;
if(times==3)
{
if(sum+now==24||sum-now==24||sum*now==24)
flag=false;
if(now!=0&&sum%now==0&&sum/now==24)
flag=false;
return;
}
//先计算前面的一部分
dfs(sum+now,num[times+1],times+1);
dfs(sum-now,num[times+1],times+1);
dfs(sum*now,num[times+1],times+1);
if(now!=0&&sum%now==0)
dfs(sum/now,num[times+1],times+1);
//再计算后面一部分
dfs(sum,now+num[times+1],times+1);
dfs(sum,now-num[times+1],times+1);
dfs(sum,now*num[times+1],times+1);
if(num[times+1]!=0&&now%num[times+1]==0)
dfs(sum,now/num[times+1],times+1);
}
int main()
{
char ch[6];
while(~scanf("%s",ch))
{
flag=true;
if(strlen(ch)==2)//除了数字10之外,所有的数字都是一位字符来表示的e
num[0]=10;
else
{
if(ch[0]=='A')
num[0]=1;
else if(ch[0]=='J')
num[0]=11;
else if(ch[0]=='Q')
num[0]=12;
else if(ch[0]=='K')
num[0]=13;
else num[0]=ch[0]-'0';
}
for(int i=1; i<=3; i++)
{
scanf("%s",ch);
if(strlen(ch)==2)//除了数字10之外,所有的数字都是一位字符来表示的e
num[i]=10;
else
{
if(ch[0]=='A')
num[i]=1;
else if(ch[0]=='J')
num[i]=11;
else if(ch[0]=='Q')
num[i]=12;
else if(ch[0]=='K')
num[i]=13;
else num[i]=ch[0]-'0';
}
}
sort(num,num+4);
do
{
dfs(num[0],num[1],1);
}
while(next_permutation(num,num+4)&&flag);//全排列函数来枚举四个数字的任意的顺序
if(!flag)//只要有一种情况计算出来结果
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
HDU 1427 速算24点 (深搜)的更多相关文章
- hdu 1427 速算24点
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1427 速算24点 Description 速算24点相信绝大多数人都玩过.就是随机给你四张牌,包括A( ...
- hdu 1427 速算24点【暴力枚举】
速算24点 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- hdu 1427 速算24点 dfs暴力搜索
速算24点 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem De ...
- HDU 1427 速算24点【数值型DFS】
速算24点 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- 24点游戏&&速算24点(dfs)
24点游戏 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...
- hdu1427之速算24点
速算24点 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- Hdu1427 速算24点 2017-01-18 17:26 46人阅读 评论(0) 收藏
速算24点 Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submiss ...
- hdu 5648 DZY Loves Math 组合数+深搜(子集法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5648 题意:给定n,m(1<= n,m <= 15,000),求Σgcd(i|j,i&am ...
- HDU 2553 N皇后问题 (深搜)
题目链接 Problem Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上. 你的任务是,对 ...
随机推荐
- L2 L3 L4
第二层交换机,是根据第二层数据链路层的MAC地址和通过站表选择路由来完成端到端的数据交换的.因为站表的建立与维护是由交换机自动完成,而路由器又是属于第三层设备,其寻址过程是根据IP地址寻址和通过路由表 ...
- Kafka高可用实现
数据存储格式 Kafka的高可靠性的保障来源于其健壮的副本(replication)策略.一个Topic可以分成多个Partition,而一个Partition物理上由多个Segment组成. Seg ...
- PHP中测试in_array、isset、array_key_exists性能
测试in_array.isset.array_key_exists性能.自己写的简易测试代码: ini_set('display_errors',true); error_reporting(E_AL ...
- matlab gradient 和 prctile
介绍两个matlab小函数: 1.gradient 借用别人的例子:例:>> x=[6,9,3,4,0;5,4,1,2,5;6,7,7,8,0;7,8,9,10,0]x = 6 ...
- Executors提供的四种线程池和自定义线程池
JAVA并发编程——EXECUTORS 线程池的思想是一种对象池的思想,开放一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完毕,对象 ...
- Scrapy初尝试
,python3.6版本 在看网上的安装的时候下一堆依赖,其实没有必要一个个的去装,pip直接分析依赖一块下载安装下来! 已经安装了pip模块 直接上 pip install scrapy 安装twi ...
- 【刷题】BZOJ 3994 [SDOI2015]约数个数和
Description 设d(x)为x的约数个数,给定N.M,求 Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组数. 接下来的T行,每行两个整数N.M. Output T ...
- Vue设置页面的title
原文地址:http://www.cnblogs.com/JimmyBright/p/7410771.html 前端框架如Vue.React等都是单页面的应用,也就是说整个web站点其实都是一个inde ...
- 51nod 1218 最长递增子序列 | 思维题
51nod 1218 最长递增子序列 题面 给出一个序列,求哪些元素可能在某条最长上升子序列中,哪些元素一定在所有最长上升子序列中. 题解 YJY大嫂教导我们,如果以一个元素结尾的LIS长度 + 以它 ...
- xml的相关知识