速算24点

题目:简单搜索&&进阶搜索 - Virtual Judge (vjudge.net)

涉及知识点:

字典序全排列函数(​​​​​​(2条消息) 【用法总结】C++ STL中 next_permutation函数的用法_荷叶田田_的博客-CSDN博客_next_permutation)+dfs

题解:

        1.这个题目最重要的一点就是要知道,(a @ b) @ (c @ d),(a @ b) @ (c @ d),只有这两个组合要考虑。所有的排列都可以化成这两种中的其中一种。

        2.利用字典序的排列函数,可以将所有排列的情况考虑一遍。建议把推荐的字典序排列函数搞明白。也可以将下面的sort函数改写,变成从大到小排序,然后while(prev_permutation(a,a+4));

        3.利用三个for循环嵌套,把所有符号的使用情况都遍历一遍。注意除法的时候要特殊考虑一下。

        4.要注意输入的时候,不能用while(1),不然会时间超限。

        5.这个题目24与-24都是正确答案。

代码如下:

#include<cstring> 
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int inf=9999999;
char b[4][3];
int a[4]; 
int sign;
int shu(int x,int y,int n)
{
	if(n==1)  return x+y;//加 
	if(n==2)  return x-y;//减 
	if(n==3)  return x*y;//乘 
	if(n==4)//除 
	{
		if(y!=0&&x%y==0)
		return x/y;
		else 
		return inf;
	}
}
int main()
{
	while(scanf("%s%s%s%s",b[0],b[1],b[2],b[3])!=EOF)
	{
	sign=0;
	for(int i=0;i<4;i++)
	{
	if(b[i][0]=='A')       a[i]=1;
	else if(b[i][0]=='J')  a[i]=11;
	else if(b[i][0]=='Q')  a[i]=12;
	else if(b[i][0]=='K')  a[i]=13;
	else if(b[i][0]=='1')  a[i]=10;
	else                   a[i]=b[i][0]-'0';
	}
	sort(a,a+4);//为全排序做准备
	do{
		for(int i=1;i<=4;i++)
		{
			for(int j=1;j<=4;j++)
			{
				for(int k=1;k<=4;k++)
				{
					int ans1=shu(shu(a[0],a[1],i),shu(a[2],a[3],j),k);
					int ans2=shu(shu(shu(a[0],a[1],i),a[2],j),a[3],k);
					if(ans1==24||ans2==24||ans1==-24||ans2==-24)
					{
					sign=1;
					break;
					}
				}
				if(sign==1)
				break;
			}
			if(sign==1)
			break;
		}
	}while(next_permutation(a,a+4));
	if(sign==1)
	cout<<"Yes"<<endl;
	else
	cout<<"No"<<endl;
	}
	return 0;
}

注意:这个题目容易卡时间不过;

下面这个题目也是计算24

题目:题目详情 - 7-8 h0115. 算24 (pintia.cn)

题解:

        1.这个题目我是用递归做的,这个题目可以出现小数,还有精度问题。

        2.这个题目的思路是一直用两个数加减乘除合成一个数,把没有使用的数放在另一个数组里面,然后再把合成的这个数放入没有使用的数的数组里面。结束条件是数组长度变成1。

#include<bits/stdc++.h>
using namespace std;
double x[5];
int sign;
int shu(double i)
{
	if(fabs(i)<=1e-7)//精度问题 
	return 1;
	return 0;
}
int find(double a[],int len)
{
	if(len==1)
	{
		double t=a[1]-24;
		if(shu(t)==1)
		{
		sign=1;
		return 1;
		}
	}
	for(int i=1;i<=len;i++)
	{
		for(int j=1;j<=len;j++)//取两个不同的数,进行加减乘除 
		{
			if(i==j)
			continue;
			int l=1;
			double t[5];//要把新和成的数组放在这里,不然会有数据过不了,设成全局变量会保存以前的数据 
			for(int k=1;k<=len;k++)
			{
				if(k!=i&&k!=j)
				t[l++]=a[k];
			}
			//加
			t[l]=a[i]+a[j];
			find(t,l); 
			//减
			t[l]=a[i]-a[j];
			find(t,l);
			t[l]=a[j]-a[i];
			find(t,l);
			//乘
			t[l]=a[i]*a[j];
			find(t,l);
			//除 
			if(a[i]!=0)
			{
				t[l]=a[j]/a[i];
				find(t,l);
			}
			if(a[j]!=0)
			{
				t[l]=a[i]/a[j];
				find(t,l);	
			}
		}
	}
}
int main()
{
	while(1)
	{
		for(int i=1;i<=4;i++)
		scanf("%lf",&x[i]);
		if(x[1]==0&&x[2]==0&&x[3]==0&&x[4]==0)
		break;
		sign=0;
		find(x,4);
		if(sign==1)
		printf("YES\n");
		else
		printf("NO\n");
	}
	return 0;	
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值