CSUOJ 1600 Twenty-four point (判断24点,另附给出表达式版)

本文介绍了一种解决24点游戏的算法实现方法,利用深度优先搜索(DFS)策略来判断给定的四个数字是否能通过加减乘除运算得到24。文章提供了两段C++代码示例,分别展示了基本的解题方法和如何进一步输出解的个数及所有可能的解。


1600: Twenty-four point

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 296   Solved: 38
[ Submit][ Status][ Web Board]

Description

Given four numbers, can you get twenty-four through the addition, subtraction, multiplication, and division? Each number can be used only once.

Input

The input consists of multiple test cases. Each test case contains 4 integers A, B, C, D in a single line (1 <= A, B, C, D <= 13).

Output

For each case, print the “Yes” or “No”. If twenty-four point can be get, print “Yes”, otherwise, print “No”.

Sample Input

2 2 3 9
1 1 1 1 
5 5 5 1

Sample Output

Yes
No
Yes

HINT

For the first sample, (2/3+2)*9=24.


题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1600

题目大意:给四个数判断能否算出24

题目分析:直接DFS爆搜,每次计算两个数字再放进数组,知道数组里只有一个数为止


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
double EPS = 1e-10;
double num[4];
bool flag;

bool equel(double a, double b)
{
	if(fabs(a - b) <= EPS)
		return true;
	return false;
}

void DFS(int n)
{
	if(flag || (n == 1 && equel(num[0], 24)))
	{
		flag = true;
		return;
	}
	for(int i = 0; i < n; i++)
	{
		for(int j = i + 1; j < n; j++)
		{
			double c1 = num[i], c2 = num[j];
			num[j] = num[n - 1];
			num[i] = c1 + c2;
			DFS(n - 1);
			num[i] = c1 - c2;
			DFS(n - 1);
			num[i] = c2 - c1;
			DFS(n - 1);
			num[i] = c1 * c2;
			DFS(n - 1);
			if(!equel(c2, 0))
			{
				num[i] = c1 / c2;
				DFS(n - 1);
			}
			if(!equel(c1, 0))
			{
				num[i] = c2 / c1;
				DFS(n - 1);
			}
			num[i] = c1;
			num[j] = c2;
		}
	}
}

int main()
{
	while(scanf("%lf %lf %lf %lf", &num[0], &num[1], &num[2], &num[3]) != EOF)
	{
		flag = false;
		DFS(4);
		printf("%s\n", flag ? "Yes" : "No");
	}
}


另外考虑,输出解的个数和所有解的方法,其实只要用字符串记录一下就可以了


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <string>
using namespace std;
double EPS = 1e-10;
double num[4];
bool flag;
int cnt;
string re[4];

bool equel(double a, double b)
{
	if(fabs(a - b) <= EPS)
		return true;
	return false;
}

void DFS(int n)
{
	if(n == 1 && equel(num[0], 24))
	{
		cnt ++;
		cout << re[0] << endl;
		return;
	}
	for(int i = 0; i < n; i++)
	{
		for(int j = i + 1; j < n; j++)
		{
			double c1 = num[i], c2 = num[j];
			string re1, re2;
			num[j] = num[n - 1];
			num[i] = c1 + c2;
			re1 = re[i];
			re2 = re[j];
			re[j] = re[n - 1];
			re[i] = '(' + re1 + '+' + re2 + ')';
			DFS(n - 1);
			num[i] = c1 - c2;
			re[i] = '(' + re1 + '-' + re2 + ')';
			DFS(n - 1);
			num[i] = c2 - c1;
			re[i] = '(' + re2 + '-' + re1 + ')';
			DFS(n - 1);
			num[i] = c1 * c2;
			re[i] = '(' + re1 + '*' + re2 + ')';
			DFS(n - 1);
			if(!equel(c2, 0))
			{
				num[i] = c1 / c2;
				re[i] = '(' + re1 + '/' + re2 + ')';
				DFS(n - 1);
			}
			if(!equel(c1, 0))
			{
				num[i] = c2 / c1;
				re[i] = '(' + re2 + '/' + re1 + ')';
				DFS(n - 1);
			}
			num[i] = c1;
			num[j] = c2;
			re[i] = re1;
			re[j] = re2;
		}
	}
}

int main()
{
	while(scanf("%lf %lf %lf %lf", &num[0], &num[1], &num[2], &num[3]) != EOF)
	{
		re[0] = num[0] + '0';
		re[1] = num[1] + '0';
		re[2] = num[2] + '0';
		re[3] = num[3] + '0';
		cnt = 0;
		DFS(4);
		printf("Answer num: %d\n", cnt);
	}
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值