我来帮你计算24点

背景

24点是一个非常有意思的纸牌游戏,我在大学的时候经常和那几个关系非常好的朋友同学一起去三三玩24点游戏,只是那美好的时光一去不复返。游戏规则是这样的:

将4张扑克正面放在桌面上,玩家使用简单的四则运算对四张牌进行计算,使得计算结果等于24,每张牌只能使用一次

那时候真的玩的不亦乐乎,cyy平时虽然傻里傻气的,但是玩24点真的一点都不含糊,总是很快就能得出答案。然后,为了能与之一战,我用C语言写了一个计算24点的程序。本来就不是计算机专业出身,所以当时写的代码虽然能够实现功能,但是代码风格太差,不忍卒睹。现在感慨往昔的日子,所以又用C++的代码重新写了一个。

24点计算原理

计算24点的原理并不复杂,因为是4个数字,3个运算符,所以总共要做3步运算。
第一步: 从 a,b,c,d 四个数字中选出a,b(任意两个)进行计算,得到e
第二步: 从c,d,e三个数字中选出c,d(任意两个)进行计算,得到f
第三步: e,f 进行计算,判断结果是否等于24

代码实现原理

因为只有4个数字,本来计算量就不大,所以我采用穷举递归的方式来实现,详情见实际代码
###代码

#include <iostream>
#include <cmath>
#include <vector>

std::vector<double> calcNums;
std::vector<char>   calcOps;

bool calc(std::vector<double> lst);

void printSolution()
{
	std::cout << "=======================================" << std::endl;
	for(int expr = 2; expr >= 0; --expr)
	{
		std::cout << "Step" << 3 - expr << ": " ;
		std::cout << calcNums[expr * 3] << calcOps[expr] << calcNums[expr * 3 + 1] << "=" << calcNums[expr * 3 + 2] << std::endl;
	}
	std::cout << "=======================================" << std::endl;
	//calcNums.clear();
	//calcOps.clear();
}
void record(double num1, double num2, double num3, char op)
{
	calcNums.push_back(num1);
	calcNums.push_back(num2);
	calcNums.push_back(num3);
	calcOps.push_back(op);
}
bool try_add(std::vector<double> &lst,double &num1, double &num2)
{
	lst.push_back(num1 + num2);
	if(calc(lst)) 
	{
		record(num1,num2,num1+num2,'+');
		return true;
	}
	else
	{
		lst.pop_back();
		return false;
	}
}
bool try_minus(std::vector<double> &lst,double &num1, double &num2)
{
	lst.push_back(fabs(num1 - num2));
	if(calc(lst)) 
	{
		if(num1 > num2) record(num1,num2,num1-num2,'-');
		else	record(num2,num1,num2-num1,'-');
		return true;
	}
	else
	{
		lst.pop_back();
		return false;
	}
}
bool try_times(std::vector<double> &lst,double &num1, double &num2)
{
	lst.push_back(num1 * num2);
	if(calc(lst)) 
	{
		record(num1,num2,num1*num2,'*');
		return true;
	}
	else
	{
		lst.pop_back();
		return false;
	}
}
bool try_divide(std::vector<double> &lst,double &num1, double &num2)
{
	lst.push_back(num1 / num2);
	if(calc(lst)) 
	{
		record(num1,num2,num1 / num2,'/');
		return true;
	}
	else lst.pop_back();
	lst.push_back(num2 / num1);
	if(calc(lst)) 
	{
		record(num2,num1,num2 / num1,'/');
		return true;
	}
	else 
	{
		lst.pop_back();
		return false;
	}
}
bool calc(std::vector<double> lst)
{
	if(lst.size() > 1)
	{
		for(int i = 0; i < lst.size() - 1; ++i)
		{
			for(int j = i+1; j < lst.size(); ++j)
			{
				std::vector<double> newLst;
				for(int k = 0; k < lst.size(); ++k)
				{
					if(k != i && k != j)
					{
						newLst.push_back(lst[k]);
					}
				}
				if(try_add(newLst,lst[i],lst[j])   || 
				   try_minus(newLst,lst[i],lst[j]) || 
				   try_divide(newLst,lst[i],lst[j])|| 
				   try_times(newLst,lst[i],lst[j]))
				{
					return true;
				}
			}
		}
		return false;
	}
	else
	{
		return (fabs(lst[0] - 24) <= 0.0001);
	}
}
int main(int argc, char** argv)
{
	double nums[4] = {0};
	std::cout << "Input 4 integers: ";
	std::cin >> nums[0] >> nums[1] >> nums[2] >> nums[3];
	std::vector<double> numbers;
	for(int idx = 0; idx < 4; ++idx)
	{
		numbers.push_back(nums[idx]);
	}
	if(calc(numbers))
	{
		printSolution();
	}
	else
	{
		std::cout << "These 4 numbers CANNOT calculate to 24!" << std::endl;
	}
}

运行结果

这里写图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值