[DFS] P1236 算24点 ( 普及+/提高

Date:2019/10/25
Degree of difficulty: ( 普及+/提高
Original question:P1236 算24点

在这里插入图片描述

→ H a p p y − b e g i n i n g \to Happy- begining Happybegining

24点,一个从小就开始玩的游戏
小学奥数终于又对我下手了

这道题有多种解法,一个就是dfs爆搜,题解上还有后缀表达式和栈来做的,我还是不太会数据结构,就先用dfs写了

先看目录

  1. dfs思路
  2. 坑点
  3. AC code

dfs思路

二十四点,如果做运算的话,每次肯定会有两个数变成一个数,
在这里插入图片描述
每次都是两个数变成一个数,而运算就只有四种情况,+ - * /
所以我们得到一个思路,分四步dfs
每次将运算完的结果存到1个数中,并把另一个数打上标记,
这样经过3步就可以得到最后的一个数。

如在2+1 = 3中,我们抽出2 和 1 进行运算,得到的结果是3,那么就用3来更新第一个数1,并把2打上标记,下一次就不挑这个位置了;

这时,我们只需判断最后的计算结果是不是24就可以了

坑点

!
在这里插入图片描述
这就要求我们在dfs中注意存贮的问题,具体见代码
思路是:用一个数组,把每次运算的两个数字存起来,再把运算符用数字代替再存起来;
输出的时候在判断;

AC code

#include<bits/stdc++.h>
#include<cstdlib>
using namespace std;
int a[4][4],num[5],fl=-1;

bool check (){						//判断函数,看最后结果是不是24
	for(int i = 1; i <= 4;i++){
		if(num[i]==24){
			return true;
		}
	}
	return false;
}

void print(){						//输出函数
	for(int i = 1; i <= 3; i ++){
		if(a[i][1]<a[i][3])	swap(a[i][1],a[i][3]);//让大数放在前面
		
		printf("%d",a[i][1]);
		if(a[i][2]==1)	printf("+");
		if(a[i][2]==2)	printf("-");
		if(a[i][2]==3)	printf("*");
		if(a[i][2]==4)	printf("/");
		printf("%d",a[i][3]);
		if(a[i][2]==1)	printf("=%d\n",a[i][1]+a[i][3]);
		if(a[i][2]==2)	printf("=%d\n",a[i][1]-a[i][3]);
		if(a[i][2]==3)	printf("=%d\n",a[i][1]*a[i][3]);
		if(a[i][2]==4)	printf("=%d\n",a[i][1]/a[i][3]);
	}
}

void dfs(int t){
	if(t == 4){
		if(check()){
			fl = 1;
			print();
			exit(0);
		}
	}
	int x,y;
	
	for(int i = 1; i <= 4;i++){
		for(int j = 1; j <= 4; j++){
			if(i != j && num[i] > 0 && num[j] >0){
				
				x = num[i]; y = num [j];		//加 
				a[t][1] = x,a[t][3] = y;
				a[t][2] = 1;
				num[i] = x + y;
				num[j] = -1; 						//相当于打标记
				dfs(t+1);
				num[i] = x; num[j] = y;				//回溯
				
				x = num[i]; y = num [j];		//减 
				a[t][1] = x,a[t][3] = y;
				a[t][2] = 2;
				num[i] = x - y;
				num[j] = -1; 
				dfs(t+1);
				num[i] = x; num[j] = y;				//回溯
				
				x = num[i]; y = num [j];		//乘 
				a[t][1] = x,a[t][3] = y;
				a[t][2] = 3;
				num[i] = x * y;
				num[j] = -1; 
				dfs(t+1);
				num[i] = x; num[j] = y;				//回溯
				
				if((num[j] != 0) && (num [i] % num[j] == 0)){
					x = num[i]; y = num [j];	//除法 
					a[t][1] = x,a[t][3] = y;
					a[t][2] = 4;
					num[i] = x / y;
					num[j] = -1; 
					dfs(t+1);
					num[i] = x; num[j] = y;
				} 
			}
		}
	}
}
int main(){
	for(int i = 1; i <= 4; i++){
		scanf("%d",&num[i]);
	}
	dfs(1);
	if(fl == -1){
		printf("No answer!");
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值