题目:简单搜索&&进阶搜索 - 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;
}