P1236 算24点

P1236 算24点

题目链接
题目描述
几十年前全世界就流行一种数字游戏,至今仍有人乐此不疲.在中国我们把这种游戏称为“算24点”。您作为游戏者将得到4个1~9之间的自然数作为操作数,而您的任务是对这4个操作数进行适当的算术运算,要求运算结果等于24。

您可以使用的运算只有:+,-,,/,您还可以使用()来改变运算顺序。注意:所有的中间结果须是整数,所以一些除法运算是不允许的(例如,(22)/4是合法的,2*(2/4)是不合法的)。下面我们给出一个游戏的具体例子:

若给出的4个操作数是:1、2、3、7,则一种可能的解答是1+2+3*7=24。

输入格式
只有一行,四个1到9之间的自然数。

输出格式
如果有解的话,只要输出一个解,输出的是三行数据,分别表示运算的步骤。其中第一行是输入的两个数和一个运算符和运算后的结果,第二行是第一行的结果和一个输入的数据、运算符、运算后的结果,或者是另外两个数的输出结果;第三行是前面的结果第二行的结果或者剩下的一个数字、运算符和“=24”。如果两个操作数有大小的话则先输出大的。

如果没有解则输出“No answer!”

如果有多重合法解,输出任意一种即可。

注:所有运算结果均为正整数

输入输出样例
输入
1 2 3 7
输出
2+1=3
7*3=21
21+3=24

想法

显然就是要组成一个表达式计算a?b?c?d是否等于24(至于括号可以在表达式出来之后再加);
判定其是否等于24,然后再输出计算过程,所以我的想法就是在
递归的过程中把算式记录下来;
方法如下

//定义一个结构体,保存数字和符号
// 1-> +
// 2-> -
// 3-> *
// 4-> /
struct node{
	int num,fh;
}cun[10];

在递归的过程中选择数据和符号,得到表达式。

int a[10];//用于存储4个数。
int book[10];
void dfs(int s){
	
	for(int i=1;i<=4;i++){
		if(book[i])
		 continue;
		book[i]=1;
		cun[s].num=a[i];
		for(int j=1;j<=4;j++){
			cun[s].fh=j;
			dfs(s+1);
		}
		book[i]=0;
	}
}

在得到表达式之后,我们就可以加括号,来计算结果。
有4 种加括号的方法(为保证不重不漏,从不加括号到一个括号再到两个,三个)
1.a?b?c?d
2.(a?b?c)?d
3.a?(b?c?d)
4.(a?b)?c?d
5.a?(b?c)?d
6.a?b?(c?d)
因为加减乘除算数的时候有优先级,前六种在光有一个算式外加一个括号的条件下,还要确定另外两个符号的优先级,在判定优先级的过程中,实际上是相当于又给算式加了括号,会和后面的算式重复,故前六种无效。
7.(a?b)?(c?d)
8.((a?b)?c)?d
9.(a?(b?c))?d
10.a?((b?c)?d)
11.a?(b?(c?d))
后五种中8,9,10,11其实是等效的,也就相当于只有
7和8两种加括号的方式。

// 1 -> +
// 2 -> -
// 3 -> *
// 4 -> /
int js(int a, int b, int k) {
	if (k == 1)
		return a + b;
	if (k == 2)
		return a - b;
	if (k == 3)
		return a *b;
	if (k == 4) {
		if (b == 0) return -1000;
		if (a % b != 0||a<b)
			return -10000;
		else return a/b;
	}
}

void dfs(int s){
	if(s==5){
		int ans=cun[1].num;
		//按方案8计算
		for(int i=1;i<=3;i++)
			ans=(ans,cun[i+1].num,cun[i].fh);
		//按方案7计算
		if(ans!=24){
			int x=js(cun[1].num,cun[2].num,cun[1].fh);
			int y=js(cun[3].num,cun[4].num,cun[3].fh);
			int z=js(x,y,cun[2].fh);
		}
		
	}



}

最后附上完整代码

#include<bits/stdc++.h>
using namespace std;
int a[10],book[10],flag=0;
struct node {
	int num;
	int fh;
}cun[10];
// 1 -> +
// 2 -> -
// 3 -> *
// 4 -> /
int js(int a, int b, int k) {
	if (k == 1)
		return a + b;
	if (k == 2)
		return a - b;
	if (k == 3)
		return a *b;
	if (k == 4) {
		if (b == 0) return -1000;
		if (a % b != 0||a<b)
			return -10000;
		else return a/b;
	}
}
void sc(int a,int b,int k) {
	if (k == 1) 
		printf("%d+%d=%d\n", max(a, b), min(a, b), a + b);
	if (k == 2) 
		printf("%d-%d=%d\n", a, b, a - b);
	if (k == 3) 
		printf("%d*%d=%d\n", max(a, b), min(a, b), a * b);
	if (k == 4) 
		printf("%d/%d=%d\n", a, b, a / b);
}
void dfs(int s) {
	if (s == 5) {
		int ans = cun[1].num;
		for (int i = 1; i <= 3; i++) 
			ans=js(ans, cun[i + 1].num, cun[i].fh);
		
		if (ans != 24) {
			int x = js(cun[1].num,cun[2].num,cun[1].fh);
			int y = js(cun[3].num,cun[4].num,cun[3].fh);
			if (js(x, y, cun[2].fh) == 24) {
				flag = 1;
				sc(cun[1].num, cun[2].num, cun[1].fh);
				sc(cun[3].num, cun[4].num, cun[3].fh);
					sc(x, y, cun[2].fh);
				return;
			}
		}
		if (ans == 24) {
			flag = 1;
			int sum = cun[1].num;
			for (int i = 1; i <= 3; i++) {
				int k = cun[i].fh;
				sc(sum, cun[i + 1].num, k);
				sum=js(sum, cun[i + 1].num, k);
			}
		}
		
		return;
	}
	for (int i = 1; i <= 4; i++) {
		if (book[i]) continue;
		book[i] = 1;
		cun[s].num = a[i];
		for (int j = 1; j <= 4; j++) {
			cun[s].fh = j;
			dfs(s + 1);
			if (flag)
				return;
		}
		book[i] = 0;
	}
}
int main() {
	memset(book, 0, sizeof(book));
	for (int i = 1; i <= 4; i++)
		scanf("%d", &a[i]);
	dfs(1);
	if (flag == 0)
		printf("No answer!");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值