• 24点游戏&&速算24点(dfs)


    24点游戏

    Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
     

    2424点就是给你一串数字,问你是否通过加减乘除括号构成2424点。

    沈爷觉得这个很好玩,就决定考考你,给你44个数,可以交换位置,可以用加减乘除和括号,是否能构成2424点呢?

    注意哦~这里的除法并不是整数除法,比如样例

    Input

    第一行TT,表示有多少组测试数据,1T501≤T≤50

    接下来TT行,每行44个正整数a1a1, a2a2, a3a3, a4a4,表示每个数都是多少,1ai131≤ai≤13

    Output

    对于每一次询问,如果能够凑成2424点,输出yes,否则输出no

    Sample input and output

    Sample InputSample Output
    2
    3 3 8 8
    1 1 1 1
    yes
    no

    Hint

    33 33 88 88

    就可以构造出 8÷(38÷3)=24

    题解:求24点,暴力搜索下就好,刚开始我想着全排列下,然后按照顺序来进行,但是思路明显不完善,然后看了大神的,

    大神是延长数组存放当前运算的解,vis记录是否用过,思路很巧妙;很简单就A过了;

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<map>
    #include<string>
    #include<vector>
    using namespace std;
    const int INF=0x3f3f3f3f;
    #define SI(x) scanf("%d",&x)
    #define PI(x) printf("%d",x)
    #define P_ printf(" ")
    #define mem(x,y) memset(x,y,sizeof(x))
    typedef long long LL;
    int flot;
    double a[110];
    int vis[110];
    /*void dfs(int pos,double cur);
    void ary(int num){
        if(flot)return;
        if(num==4){
        //    for(int i=0;i<4;i++)printf("%d ",ans[i]);puts("");
            dfs(1,ans[0]);
            return;
        }
        for(int i=0;i<4;i++){
            if(vis[i])continue;
            ans[num]=a[i];
            vis[i]=1;
            ary(num+1);
            vis[i]=0;
        }
    }
    */
    void dfs(int usd,int tp){
        if(flot)return;
        if(usd==4){
            if(abs(a[tp-1]-24)<1e-8)flot=1;
            return;
        }
        /*
        dfs(pos+1,cur+ans[pos]);
        dfs(pos+1,cur-ans[pos]);
        dfs(pos+1,cur*ans[pos]);
        dfs(pos+1,cur/ans[pos]);
        dfs(pos+1,-cur*ans[pos]);
        dfs(pos+1,-cur/ans[pos]);
        dfs(pos+1,ans[pos]/cur);
        dfs(pos+1,ans[pos]/cur);
        */
        for(int i=0;i<tp;i++){
            if(vis[i])continue;
            vis[i]=1;
            for(int j=i+1;j<tp;j++){
                if(vis[j])continue;
                vis[j]=1;
                a[tp]=a[i]+a[j];dfs(usd+1,tp+1);
                a[tp]=a[i]*a[j];dfs(usd+1,tp+1);
                a[tp]=a[i]-a[j];dfs(usd+1,tp+1);
                a[tp]=a[j]-a[i];dfs(usd+1,tp+1);
                if(a[i]!=0){
                    a[tp]=a[j]/a[i];dfs(usd+1,tp+1);
                }
                if(a[j]!=0){
                    a[tp]=a[i]/a[j];dfs(usd+1,tp+1);
                }
                vis[j]=0;
            }
            vis[i]=0;
        }
    }
    int main(){
        int T;
        SI(T);
        while(T--){
            for(int i=0;i<4;i++)scanf("%lf",&a[i]);
            flot=0;
            mem(vis,0);
            dfs(1,4);
            if(flot)puts("yes");
            else puts("no");
        }
        return 0;
    }

    速算24点

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4250    Accepted Submission(s): 1044

    Problem Description
    速算24点相信绝大多数人都玩过。就是随机给你四张牌,包括A(1),2,3,4,5,6,7,8,9,10,J(11),Q(12),K(13)。要求只用'+','-','*','/'运算符以及括号改变运算顺序,使得最终运算结果为24(每个数必须且仅能用一次)。游戏很简单,但遇到无解的情况往往让人很郁闷。你的任务就是针对每一组随机产生的四张牌,判断是否有解。我们另外规定,整个计算过程中都不能出现小数。
     
    Input
    每组输入数据占一行,给定四张牌。
     
    Output
    每一组输入数据对应一行输出。如果有解则输出"Yes",无解则输出"No"。
     
    Sample Input
    A 2 3 6 3 3 8 8
     
    Sample Output
    Yes No


    题解:跟上题不同的是,这个是字符输入,而且,是整除的;注意10的读入。。。

    虽然写过,但是比赛出到还是不会。。。这个题思路就是dfs,a[tp - 1]代表当前usd的个数的计算值。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std;
    int a[1010];
    int vis[1010];
    int ans;
    void dfs(int usd, int tp){
        if(ans)return;
        if(usd == 4){
            if(a[tp - 1] == 24)ans = 1;
            return;
        }
        for(int i = 0; i < tp; i++){
            if(vis[i])continue; 
            vis[i] = 1;
            for(int j = i + 1; j < tp; j++){//注意应该从i + 1开始,可以让时间减少一般否则会超时; 
                if(vis[j])continue;
                vis[j] = 1;
                a[tp] = a[i] + a[j];dfs(usd + 1, tp + 1);
                a[tp] = a[i] - a[j];dfs(usd + 1, tp + 1);
                a[tp] = a[j] - a[i];dfs(usd + 1, tp + 1);
                a[tp] = a[i] * a[j];dfs(usd + 1, tp + 1);
                
                if(a[j] != 0 && a[i] % a[j] == 0){
                    a[tp] = a[i] / a[j];dfs(usd + 1, tp + 1);
                }
                if(a[i] != 0 && a[j] % a[i] == 0){
                    a[tp] = a[j] / a[i];dfs(usd + 1, tp + 1);
                }
                
                vis[j] = 0;
            }
            vis[i] = 0;
        }
    }
    int main(){
        char s[4][4];
        while(~scanf("%s %s %s %s",s[0],s[1],s[2],s[3])){
            for(int i =0;i < 4;i++){
                if(strlen(s[i]) == 2)a[i] = 10;
                else if(s[i][0] == 'A')a[i] = 1;
                else if(s[i][0] == 'J')a[i] = 11;
                else if(s[i][0] == 'Q')a[i] = 12;
                else if(s[i][0] == 'K')a[i] = 13;
                else a[i] = s[i][0] - '0';
            }
            ans = 0;
            memset(vis, 0, sizeof(vis));
            dfs(1, 4);
            if(ans)
                puts("Yes");
            else
                puts("No");
        }
        return 0;
    }
  • 相关阅读:
    How to install tcpping on Linux.md
    当前服务器的并发连接数查看
    Windows 系统下安装 dig 命令
    paping使用来测试联通&网站由于tcp协议导致的无法通信问题超时问题
    SSH反向连接及Autossh
    设置Windows Azure Linux虚拟机中的root账户
    用UltraISO制作CentOS U盘安装盘
    CentOS7 修改网卡名称为eth0
    iOS开发--绘图教程
    ios开发--网页中调用JS与JS注入
  • 原文地址:https://www.cnblogs.com/handsomecui/p/5259507.html
Copyright © 2020-2023  润新知