7-5 3824经典游戏分数 20 作者 李佳单位 重庆大学

作者 李佳

单位 重庆大学

24点游戏,也叫3824游戏,是一款经典的心算数字游戏。给出区间[1,13]内的四个整数,验证能否用加、减、乘、除四则运算,将这四个整数组合成24。比如:(3,8,2,4) 可以算出 8∗(4−3+2)=24或者(8−4)∗(2∗3)=24,而(1,1,2,2)无法算出24。注意整除必须除尽,即9/2+10+10=24这种计算无效。

输入格式:

第一行给出正整数N(1≤N≤1000)。接下来N行数据,每行给出四个正整数ai​ bi​ ci​ di​, 用空格分开。(∀i∈{1,...,N}:1≤ai​,bi​,ci​,di​≤13)

输出格式:

输出N行数据,第i行对应输入数据(ai​,bi​,ci​,di​),如果能算出24,则输出24,如果不能则输出0。

输入样例:

4
1 1 1 1
1 2 3 4
3 9 11 2
13 3 5 7

输出样例:

0
24
0
24

(1,1,1,1)和(3,9,11,2)都无法算出24,(1,2,3,4)和(13,3,5,7)可以算出:1∗2∗3∗4=24和(13∗5+7)/3=24。

个人思路:

借鉴了大佬的思路,但不足以解决问题,请教了学长,知道解题算法中的缺点,改正并记录一下。

此题大意是计算4个数通过各种组合能否计算出结果24,我们通过回溯还是可以遍历每一种加减乘除的可能,唯一不足就是,此题要求考虑括号,如果我们按照顺序计算四个数,那么肯定我们是无法实现括号的优先级功能的,此时大佬的思路:双层循环简直天神下凡,我们可以用这个双层循环实现4个数中任意两个数一起计算的可能,那么括号这个大问题就算解决了。

第二个问题,在回溯过程中,由于我们是通过双层循环选取的任意两个数,对于加法,两个数先后顺序是无所谓的,但在减法和除法中,两个数先后顺序不同会产生两种不同结果,于是我们要多加一次减法和除法。

来看代码:

#include<iostream>
using namespace std;
int arr[4];
bool dfs(int n)//n初始时等于4,每进行一次计算就减1
{
	if (n == 1)  //设置终点,返回计算结果是否等于24
		return arr[0] == 24;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if (i == j) //同一个数就跳过
				continue;
			int op1 = arr[i], op2 = arr[j]; //op1和op2一会儿用来进行计算和恢复现场
			arr[i] = op1 + op2;
			arr[j] = arr[n - 1];//由于arr[j]已经被用掉了,要把此时未计算的队尾元素拿过来
			if (dfs(n - 1))
				return 1;
			arr[i] = op1 - op2;
			if (dfs(n - 1))
				return 1;
			arr[i] = op2 - op1;//减法多进行一次
			if (dfs(n - 1))
				return 1;
			arr[i] = op1 * op2;
			if (dfs(n - 1))
				return 1;
			if (op2 != 0 && op1 % op2 == 0)
			{
				arr[i] = op1 / op2;
				if (dfs(n - 1))
					return 1;
			}
			if (op1 != 0 && op2 % op1 == 0)//除法多进行一次
			{
				arr[i] = op2 / op1;
				if (dfs(n - 1))
					return 1;
			}
			arr[i] = op1;
			arr[j] = op2;
		}
	}
	return 0;
}
int main()
{
	int n;
	cin >> n;
	while (n--)
	{
		cin >> arr[0] >> arr[1] >> arr[2] >> arr[3];
		if (dfs(4))
			cout << "24" << endl;
		else cout << "0" << endl;
	}
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星河边采花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值