24 Point game(nyoj 43)

题目:点击打开链接

这个题写了我好久好久………………样例一直都过不了=  =。

24点游戏,给你几个数,看能不能构成24点。

刚看到题,想的就是对数字进行全排列然后再对符号进行全排列,还要特殊处理括号,相当麻烦.

其实这个题用不着全排列所有数字,只要每次在数组中选取两个之前没有运算过的数字进行运算,其中运算包括6种:加,减, 乘,除,被减,被除,将结果存入数组,为避免重复使用数字,要标记那两个数已经用过。m个数经过m - 1次运算就可以得到最后的结果,将最后的结果跟24进行比较,比较的时候要注意精度问题。因为随机的取数进行运算并且运算除了加,减, 乘,除,还有被减,被除,这样就可以枚举所有的组合情况,就不用进行全排列了,感觉还是挺有收获的……


#include <stdio.h>
#include <string.h>
#include <math.h>

int n;
double sum, a[10];
bool vis[10];

int dfs(int m, int top)
{//m记录运算了几次,top是下一次运算的结果存放的位置
	if(m == 1)
	{
		if(fabs(sum - a[top - 1]) < 0.000001)
			return 1;
		else
			return 0;
	}
	
	int i, j;
	for(i = 0; i < top - 1; i++)
	{
		if(!vis[i])
		{//i位置的数没有使用过
			vis[i] = 1;
			for(j = i + 1; j < top; j ++)
			{
				if(!vis[j])
				{
					vis[j] = 1;
					a[top] = a[i] + a[j];
					if(dfs(m - 1, top + 1))
						return 1;
						
					a[top] = a[i] - a[j];
					if(dfs(m - 1, top + 1))
						return 1;
						
					a[top] = a[j] - a[i];
					if(dfs(m - 1, top + 1))
						return 1;
						
					a[top] = a[i] * a[j];
					if(dfs(m - 1, top + 1))
						return 1;
						
					if(a[i] != 0)
					{
						a[top] = a[j] / a[i];
						if(dfs(m - 1, top + 1))
							return 1;
					} 
					if(a[j] != 0)
					{
						a[top] = a[i] / a[j];
						if(dfs(m - 1, top + 1))
							return 1;
					}	
					vis[j] = 0;//注意位置…………
				} 	
			}
			vis[i] = 0;//注意………
		}
	}
	return 0;	
}

int main (void)
{
	int t;
	scanf("%d", &t);
	while(t --)
	{
		memset(vis, 0, sizeof(vis));
		scanf("%d", &n);
		scanf("%lf", &sum);
		int i;
		for(i = 0; i < n; i++)
			scanf("%lf", &a[i]);
		if(dfs(n, n))
			printf("Yes\n");
		else
			printf("No\n");
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值