sicily1050-Numbers & Letters

本文分享了一次使用深度优先搜索解决复杂数学运算问题的经历,重点总结了算法实现中容易忽视的细节,包括边界条件、递归终止条件及内存管理等关键点。通过具体代码实例,强调了在实际编程中对细节严谨处理的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一道经典的深搜题,以为自己可以轻松解决的,结果犯了很多细节上的错误,都记录下来作个警示吧。

题目大意是用+-*/任意组合5个数(每种符号使用次数不限,除法要求只能是整除,每个数字只能用一次,可以不用完全部数字),使得运算res为小于等于给定target的最大值


思路是穷举5个数的排列方式,挑选另一个数与它进行叠加(+-*/),

深搜进去变成4个数,再穷举4个数的排列方式……

深搜进去变成3个数……

直到最后只剩一个数,也就是运算结果


唉这学期太忙,化在算法课上的时间好少,题都不会刷了,要好好反思一下了。

犯错点用数字标记出来了。


#include <iostream>
#include <algorithm>
using namespace std;
int num[5];
int target;
int finalres;
bool get;
 
void dfs(int* num, int level){
	if (num[level] > finalres && num[level] <= target)//①
		finalres = num[level];
	if (finalres == target){
		get = true;
		return;
	}
	if (level == 4 || get)//② 
		return;															int tmp[5];
	for (int i = level; i < 5; i++){
		for (int j = i + 1; j < 5; j++){
			int a = num[i], b = num[j], count = 4;
			for (int k = 4; k >= level; k--){//③
				if (k == i || k == j)
					continue;
				tmp[count--] = num[k];
			}						
			tmp[level + 1] = a + b;
			dfs(tmp, level + 1);
			tmp[level + 1] = a - b;
			dfs(tmp, level + 1);
			tmp[level + 1] = b - a;
			dfs(tmp, level + 1);
			tmp[level + 1] = a * b;
			dfs(tmp, level + 1);
			if (a!= 0 && b != 0 && a % b == 0){//④ 
				tmp[level + 1] = a / b;
				dfs(tmp, level + 1);
			}
			else if (a!= 0 && b != 0 && b % a == 0){
				tmp[level + 1] = b / a;
				dfs(tmp, level + 1);
			}
		}
	} 
  
}																		
int main(){
    int N, T;
    cin >> N;
    while (N--){
        for (int i = 0; i < 5; i++){
            cin >> num[i];
        }
        cin >> target;
        get = false;
        finalres = -2000000000;//⑤
		dfs(num, 0);
        cout << finalres << endl;        
    }
    return 0;
}                                 



①这个if必须放在最前面(否则若把第3个if提到首,若到level4时找到了答案,根本没对finalres赋值就return掉了),下面两个if的顺序无所谓,区别只在get没有而已,只是为了早一步结束不必要的搜索,但是并不影响结果

②当num[level]>target或是<0时不能return,因为有可能通过后面的运算再把数值拉回到范围之内,下方算a-b和b-a两种减法也是同理

③复制num数组方便传入,这种内存问题自己犯过好多次了,有强迫症希望能少用空间就少用空间,这种习惯挺好但是自己老是死在这上面,想对内存空间重复利用就必须要记得保护现场和恢复现场啊,像这一题用这种实现方法的话,这样大量开辟栈空间是不可避免的了 

④题目中只允许整除,注意下面要是elseif,防止a==b的情况算两次

⑤虽然题目说target是在[0,1000],但是这句改成-1都WA,估计是有负数输入的,究竟是num[i]还是target就不得而知了


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值