题目
思路
由于题目里说了不考虑优先级,就是从左向右顺序计算,那就简单多了,直接DFS。因为如果能够得到目标数字要输出算式,所以dfs函数的输出(记作ret)就是一个表示运算符的数,该数的每一个二进制位对应一个运算符,具体来说:
if (ret & (1<<(n-2-i))
{
oper[i] = '*';
}
else
{
oper[i] = '+';
}
由于ret取决于深搜的每层运算符的选择,所以这个数同样要作为dfs函数的一个参数输入,每次更新,最后输出。dfs函数的另外两个参数就是日常参数:i表示计算到第几个运算符,cur表示第i个运算符左边的计算结果。
还有就是如果得不到目标数字,要输出所有计算结果中大于目标数字中的最小者。对于这个要求,加一个全局变量表示大于目标数字的最小值就行了,每次如果计算结果大于目标数字,则维护更新该全局变量。
代码
#include<cstdio>
const int INF = 0x3f3f3f3f;
int n, D, minv = INF;
int a[13] = {};
int dfs(int i, int cur, int oper) // 第i-1个运算符已经放入,当前累积值为cur
// 用二进制表示运算符,0表示"+", 1表示"*", 例如001表示有++*
// 如果结果不等于D,返回-1; 否则返回一个数,每一个二进制位代表一个运算符
{
if (i == n)
{
if (cur == D)
{
return oper;
}
else if (cur > D)
{
minv = minv < cur ? minv : cur;
}
return -1;
}
int ans0 = dfs(i+1, cur + a[i+1], (oper<<1)+0); // 第i个运算符是加法
int ans1 = dfs(i+1, cur * a[i+1], (oper<<1)+1); // 第i个运算符是乘法
if (ans0 >= 0)
{
return ans0;
}
else if (ans1 >= 0)
{
return ans1;
}
else
{
return -1;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("thuSE15_02.txt", "r", stdin);
#endif
int i, ans;
scanf("%d%d", &n, &D);
for (i=0; i<n; i++)
{
scanf("%d", a+i);
}
ans = dfs(0, a[0], 0);
if (ans >= 0)
{
for (i=0; i<n-1; i++)
{
printf("%d", a[i]);
if (ans & (1<<(n-2-i)))
{
printf("*");
}
else
{
printf("+");
}
}
printf("%d", a[n-1]);
}
else
{
printf("%d", minv);
}
return 0;
}