一道c++算法题,不知道该怎么设计,求指导
用户可以输入n个数和目标D。
可使用的运算符限定于加号和乘号两种,且它们之间既没有优先级次序也不得使用括号(故计算总是按输入n个数的顺序及添加的运算符自左向右进行)。
一旦得不到目标D,希望知道一个能够通过这n个数得出的大于D的最小值。
【输入】
第一行两个正整数 N 和 D,分别表示数的个数和目标结果。第二行为 N 个数字,以空格分隔。
【输出】
若能得到D,则输出一个对应算式;否则输出No,以及大于D的最小值(最小值不存在则输出-1)。
【限制】1 ≤ N ≤ 24,1 ≤ D < 2^60
【输入样例1】
4 235
34 12 5 5
【输出样例1】
34+12*5+5
【输入样例2】
3 600
9 9 9
【输出样例2】
No
729
花了点时间,用递归和减而治之的思想。
#include <iostream>
#include <deque>
using namespace std;
void Generate(const deque<int64_t> &operands, int64_t D, deque<char> &operators, int64_t &result)
{
if (operands.size() == 1u) {
if ((operands[0] >= D) && (result == -1) || (result > operands[0])) {
result = operands[0];
}
return;
}
// 加法运算
auto tmpOperands(operands);
tmpOperands[1] += tmpOperands[0];
tmpOperands.pop_front();
operators.push_back('+');
Generate(tmpOperands, D, operators, result);
if (result == D) {
return;
}
operators.pop_back();
// 乘法运算
tmpOperands[0] = operands[0] * operands[1];
operators.push_back('*');
Generate(tmpOperands, D, operators, result);
if (result != D) {
operators.pop_back();
}
}
int main(int, char **)
{
int64_t N, D, i;
cin >> N >> D;
deque<int64_t> operands;
for (i = 0; i < N; ++i) {
int t;
cin >> t;
operands.push_back(t);
}
deque<char> operators;
int64_t result = -1;
Generate(operands, D, operators, result);
if (result == D) {
for (i = 0; i < N - 1; ++i) {
cout << operands[i] << operators[i];
}
cout << operands[i] << endl;
} else {
cout << "NO" << endl;
cout << result << endl;
}
}
二叉树,左子树表示加,右子树表示乘,构造出二叉树之后看看最下一层有没有目标就行
搜索加剪枝,看数据范围你还得写一下大数,用数组存下
暴力枚举 可以去看看cspj的笔试题“凑出17”
暴力枚举或者搜索
我能用python给你解答吗?
可以直接考虑暴力的方法,枚举每个符号的所有可能性,当有n个数字时,一共需要处理n-1个符号,每个符号有两种可能,因此一共有2的n-1次方种方案,考虑每种方案,在算出对应方案的值后,与D进行比较,大于等于D时,则将当前方案的值与已经保存的上个答案m比较,并取小的那一个。如果最后已保存的值等于D,则输出方案,大于则输出NO和已保存的值,如果过程中没有大于等于的方案则输出-1 PS:这道题数据范围较大,如果采用的方法需要算出方案具体的值,int会爆,要用long long,且暴力可能会超时
望采纳