zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    codeforces 980A Links and Pearls
    zoj 3640 Help Me Escape
    sgu 495 Kids and Prizes
    poj 3071 Football
    hdu 3853 LOOPS
    hdu 4035 Maze
    hdu 4405 Aeroplane chess
    poj 2096 Collecting Bugs
    scu 4444 Travel
    zoj 3870 Team Formation
  • 原文地址:https://www.cnblogs.com/handsomecui/p/5259507.html
Copyright © 2011-2022 走看看