vijos P1134 算24点 题解

#include  
#include 
#include 
#include 
#include 
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 
然后在外面的循环里进行两两操作(即再进行加减乘除运算) 就能得到答案

你可能感兴趣的:(vijos,题解)