问题描述
40 分, LeetCode hard 档次
• 从控制台输入一行,形如“n A1 A2 A3 … An B”。其中n代表操作数总数,A1~An 表示n 个操作数。B 代表目标数字。在此n 个操作数中以任意顺序插入n-1 个四则运算操作符,不能插入括号,形成的表达式能否得到B?能——输出1,不能——输出0。操作数和目标数字是整数,整数大小限制在32 位有符号整数范围内。
• 例如:
4 75 4 18 8 21
输出1 (75 / 4 + 18 / 8 = 21)
• 表达式求值、DFS(回溯)、栈、树
--------------------------------------------------------------------------------
思路
DFS深搜填入符号,DFS的参数是当前目标值b,返回值是“是否可以得到B”的布尔量。
用全局双端队列存储n个操作数。
由于优先级,对加/减法和乘/除法的处理略有差异。
如果是加法,则将第一个操作数a1出队,深搜求队列中剩下的数是否能拼成b-a1,记录布尔量b1 = dfs(b-a1)的结果;
如果是减法,则将第一个操作数a1出队,深搜求队列中剩下的数是否能拼成a1-b,记录布尔量b2 = dfs(a1-b)的结果;
如果是乘法,则将前两个操作数a1,a2出队,再将a1*a2插入队首,深搜求此时队列中的数是否能拼成b,记录布尔量b3 = dfs(b)的结果;
如果是除法,则将前两个操作数a1,a2出队,再将a1/a2插入队首,深搜求此时队列中的数是否能拼成b,记录布尔量b4 = dfs(b)的结果;
最后将b1/b2/b3/b4相或作为函数的返回值。
# 注意运算过程中可以出现小数,因此用float保存读入的数据和中间结果。
# 注意每次dfs过后需要回溯,即复原双端队列。
--------------------------------------------------------------------------------
代码(未经OJ测评,程序可能有误)
//清华大学软件学院2016年推研机试第3题
//
//40 分, LeetCode hard 档次
//
//从控制台输入一行,形如“n A1 A2 A3 … An B”。其中n 代
//表操作数总数,A1~An 表示n 个操作数。B 代表目标数字。
//在此n 个操作数中以任意顺序插入n-1 个四则运算操作符,
//不能插入括号,形成的表达式能否得到B?能——输出1,
//不能——输出0。操作数和目标数字是整数,整数大小限制
//在32 位有符号整数范围内。
//
//例如:
//4 75 4 18 8 21
//输出1 (75 / 4 + 18 / 8 = 21)
//
//表达式求值、DFS(回溯)、栈、树
#include<cstdio>
#include<queue>
int n;
std::deque<float> q;
bool dfs(float b)
{
float a1, a2, aa;
int s = q.size();
bool b1,b2,b3,b4;
if (s == 1)
{
return q.front() == b;
}
else
{
// +
a1 = q.front();
q.pop_front();
b1 = dfs(b-a1);
q.push_front(a1);
// -
a1 = q.front();
q.pop_front();
b2 = dfs(a1-b);
q.push_front(a1);
// *
a1 = q.front();
q.pop_front();
a2 = q.front();
q.pop_front();
aa = a1 * a2;
q.push_front(aa);
b3 = dfs(b);
q.pop_front();
q.push_front(a2);
q.push_front(a1);
// /
a1 = q.front();
q.pop_front();
a2 = q.front();
q.pop_front();
aa = a1 / a2;
q.push_front(aa);
b4 = dfs(b);
q.pop_front();
q.push_front(a2);
q.push_front(a1);
return b1 || b2 || b3 || b4;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("thuSE16_03.txt", "r", stdin);
#endif
int i;
float a, b;
scanf("%d", &n);
for (i=0; i<n; i++)
{
scanf("%f", &a);
q.push_back(a);
}
scanf("%f", &b);
printf("%d", dfs(b));
return 0;
}