uva 10400 Game Show Math

dfs题目,注意记录状态进行剪枝,否则会超时。

#include <stdio.h>
#include <set>
using namespace std;

#define		ADD		0
#define		SUB		1
#define		MUL		2
#define		DIV		3

int arr[120];
char path[120];
bool stop;
int max_index;
int target_value;

long long _hash(int cur, int value)
{
	return value*120 + cur;
}

set<long long> hash_map;
void dfs(int oper, int cur, int last_value)
{
	if(stop)
		return;

	if(cur == max_index+1)
	{
		if(last_value == target_value)
			stop = true;
		return;
	}

	int cur_value;
	long long hv;

	if(last_value<-32000 || last_value>32000)
		return;

	if(oper==DIV && last_value%arr[cur]!=0)
		return;

	switch(oper)
	{
	case ADD:
		cur_value = last_value + arr[cur];
		path[cur] = '+';
		break;
	case SUB:
		cur_value = last_value - arr[cur];
		path[cur] = '-';
		break;
	case MUL:
		cur_value = last_value * arr[cur];
		path[cur] = '*';
		break;
	case DIV:
		cur_value = last_value / arr[cur];
		path[cur] = '/';
		break;
	}

	hv = _hash(cur, cur_value);
	if(hash_map.find(hv) == hash_map.end())
		hash_map.insert(hv);
	else
		return;

	dfs(ADD, cur+1, cur_value);
	dfs(SUB, cur+1, cur_value);
	dfs(MUL, cur+1, cur_value);
	dfs(DIV, cur+1, cur_value);
}

void func(int n, int target)
{
	int i;

	hash_map.clear();

	stop = false;
	target_value = target;
	max_index = n-1;
	dfs(ADD, 1, arr[0]);
	dfs(SUB, 1, arr[0]);
	dfs(MUL, 1, arr[0]);
	dfs(DIV, 1, arr[0]);

	if(stop)
	{
		printf("%d", arr[0]);
		for(i=1; i<=n-1; i++)
			printf("%c%d", path[i], arr[i]);
		printf("=%d\n", target);
	}
	else
	{
		printf("NO EXPRESSION\n");
	}
}

int main(void)
{
	int n, m, i;
	int target;

	//freopen("input.dat", "r", stdin);

	scanf("%d", &m);
	while(m--)
	{
		scanf("%d", &n);
		for(i=0; i<n; i++)
			scanf("%d", arr+i);
		scanf("%d", &target);

		func(n, target);
	}

	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值