• bzoj1215 24点游戏


    Description

    为了培养小孩的计算能力,大人们经常给小孩玩这样的游戏:从1付扑克牌中任意抽出4张扑克,要小孩用“+”、“-”、“×”、“÷”和括号组成一个合法的表达式,并使表达式的值为24点。这种游戏就是所谓的“24点游戏”。请你编程求出对于给出的任意4个正整数a、b、c、d,请你编程求出这4个整数能组成多少个值为24的不同表达式。

    Input

    输入共一行,为4个正整数a、b、c、d (0<=a,b,c,d<=100)

    Output

    输出由a、b、c、d组成的值为24表达式个数,如没有,输出0。

    两个不加多余括号的表达式相同当且仅当仅当完全相同或通过结合律可以互相转换

    枚举可能的表达式,最多7680个,且要求表达式树中+或*的右子节点不为同优先级运算符

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #define _0 0.000001
    int v[4],rnk[4];
    int hs[8000],p=0,ans=0;
    inline void add(int v1,int v2,int v3,int v4,int v5,int v6,int v7){
        hs[p++]=(v1|v2<<3|v3<<6|v4<<9|v5<<12|v6<<15|v7<<18);
    }
    inline double f(double a,double b,int op){
        if(op==0)return a+b;
        if(op==1)return a-b;
        if(op==2)return a*b;
        return a/b;
    }
    inline bool e(int a,int b){
        if(a==0)return b>1;
        if(a==2)return b<2;
        return 1;
    }
    inline void chk(int v1,int v2,int v3,int v4){
        for(int o1=0;o1<4;o1++){
            for(int o2=0;o2<4;o2++){
                for(int o3=0;o3<4;o3++){
                    bool e1=e(o3,o2),e2=e(o2,o1);
                    if(fabs(f(f(f(v[v1],v[v2],o1),v[v3],o2),v[v4],o3)-24)<_0)add(rnk[v1],rnk[v2],o1+4,rnk[v3],o2+4,rnk[v4],o3+4);
                    if(e1&&fabs(f(f(v[v1],v[v2],o1),f(v[v3],v[v4],o2),o3)-24)<_0)add(rnk[v1],rnk[v2],o1+4,rnk[v3],rnk[v4],o2+4,o3+4);
                    if(e2&&fabs(f(f(v[v1],f(v[v2],v[v3],o1),o2),v[v4],o3)-24)<_0)add(rnk[v1],rnk[v2],rnk[v3],o1+4,o2+4,rnk[v4],o3+4);
                    if(e1&&fabs(f(v[v1],f(f(v[v2],v[v3],o1),v[v4],o2),o3)-24)<_0)add(rnk[v1],rnk[v2],rnk[v3],o1+4,rnk[v4],o2+4,o3+4);
                    if(e1&&e2&&fabs(f(v[v1],f(v[v2],f(v[v3],v[v4],o1),o2),o3)-24)<_0)add(rnk[v1],rnk[v2],rnk[v3],rnk[v4],o1+4,o2+4,o3+4);
                }
            }
        }
    }
    int main(){
        for(int i=0;i<4;i++)scanf("%d",v+i);
        for(int i=0;i<4;i++){
            for(int j=0;j<4;j++)
                if(i!=j)rnk[i]+=v[i]<v[j];
        }
        chk(0,1,2,3);
        chk(0,1,3,2);
        chk(0,2,1,3);
        chk(0,2,3,1);
        chk(0,3,1,2);
        chk(0,3,2,1);
        chk(1,0,2,3);
        chk(1,0,3,2);
        chk(1,2,0,3);
        chk(1,2,3,0);
        chk(1,3,0,2);
        chk(1,3,2,0);
        chk(2,0,1,3);
        chk(2,0,3,1);
        chk(2,1,0,3);
        chk(2,1,3,0);
        chk(2,3,0,1);
        chk(2,3,1,0);
        chk(3,0,1,2);
        chk(3,0,2,1);
        chk(3,1,0,2);
        chk(3,1,2,0);
        chk(3,2,0,1);
        chk(3,2,1,0);
        std::sort(hs,hs+p);
        if(p)ans=1;
        for(int i=1;i<p;i++)ans+=(hs[i]!=hs[i-1]);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    (转)移动端实现垂直居中的几种方法
    FloatingActionButton 完全解析
    android 开源编辑器
    如何使用PullToRefresh
    Android 使用代码主动去调用控件的点击事件(模拟人手去触摸控件)
    Gradle 下载
    android studio 中移除module和恢复module
    android studio 使用jar包,arr包和怎么使用githup开源项目中的aar包或module
    DrawerLayout 和 NavigationView 的使用
    android studio 集成微信登录
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5468365.html
Copyright © 2020-2023  润新知