2016年清华软院保研机试第3题(dfs回溯)

问题描述

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;
}

猜你喜欢

转载自blog.csdn.net/da_kao_la/article/details/82319399