#include <iostream>
#include <cstdio>
#include <math.h>
#include <string.h>
#include <string>
using namespace std;
bool used[5];
int a[5];
bool mem[1000];
double qiku[120][1001];
int ans;
void work(double now,int k)
{
if(k==5)
{
if(now==24)ans=1;
return;
}
int tot=0;
if(k==3)
{
for(int i=1;i<=4;i++)
{
if(used[i]==true)tot+=1<<(i-1);
}
//printf("%d ",tot);
int s=++qiku[tot][0];
qiku[tot][s]=now;
// printf("%.1f|%d|%d ",qiku[tot][s],tot,s);
// if (s%6==0)
// printf("\n");
}
if(ans==1)return;
for(int i=1;i<=4;i++)
{
if(used[i])continue;
used[i]=true;
work(now+a[i],k+1);
work(now-a[i],k+1);
work(a[i]-now,k+1);
work(now*a[i],k+1);
if(now!=0)
work(a[i]/now,k+1);
if(a[i]!=0)
work(now/a[i],k+1);
used[i]=false;
}
}
int main()
{
string s;
for(int i=1;i<=4;i++)
{
cin>>s;
if(s=="10")
{a[i]=10;continue;}
if(s[0]=='A') a[i]=1;
if(s[0]<'A') a[i]=s[0]-'0';
if(s[0]=='J') a[i]=11;
if(s[0]=='Q') a[i]=12;
if(s[0]=='K') a[i]=13;
}
ans=0;
memset(used,0,sizeof(used));
memset(qiku,0,sizeof(0));
for(int i=1;i<=4;i++)
{
used[i]=true;
work(a[i],2);
work(-a[i],2);
used[i]=false;
}
if(!ans)
//for(int i=1;i<=1;i+=2)
for(int i=1,j=2;j<=4;j++)
{
int tot=(1<<(i-1))+(1<<(j-1));
int b=15-tot;
for(int k=1;k<=qiku[tot][0];k++)
{
double x=qiku[tot][k];
for(int l=1;l<=qiku[b][0];l++)
{
double y=qiku[b][l];
if(x+y==24||x-y==24||y-x==24||x*y==24)ans=1;
if(x!=0&&(double)y/x==24||y!=0&&(double)x/y==24)ans=1;
}
}
}
if(ans)
printf("1\n");
else printf("0\n");
}
首先我相信函数work里面的递归大家都能理解 就是枚举各种可能 也就是说就是一个简单的dfs
主要是说后面的循环和qiku[][]这个函数的作用首先我们来看这道题 这题让我们找出四个数能否组成24 我们现在想一下 四个数用加减乘除如何能组成二十四
是不是说只用两种情况 一个是对一个数一步一步的与其他三个数进行加减乘除运算 得到24 简单的说 比如 1 2 3 4 就是用1*2=2 然后在用2*3=6 6*4=24 得出的 就是说这种是一个数 一步一步的运算 我们用dfs就可以简单的实现
还有一种情况 就是说 两两进行乘除运算 然后将得到的值进行加减运算 比如 5 5 -5 -5 就是5*5--5/-5=24 而我们的dfs无法做到让他们两两乘除运算后再做加减运算 这就是上面程序后面的循环的意义,也就是qiku[][]这个数组的作用
qiku[][]这个数组就是用来存储每两个数之间运算时得到的值 他用1 2 4 8 标记了 a b c d 四个初始的书 这样 qiku[1+2][] 就表示取ab两个数之间的运算 qiku[1+4][]表示取ac qiku[1+8][]表示取ad qiku[2+4][]表示取bc qiku[2+8][]表示取bd qiku[4+8][]表示取cd
然后在外面的循环里进行两两操作(即再进行加减乘除运算) 就能得到答案