• 洛谷P1236 算24点


    题目描述

    几十年前全世界就流行一种数字游戏,至今仍有人乐此不疲.在中国我们把这种游戏称为“算24点”。您作为游戏者将得到4个1~9之间的自然数作为操作数,而您的任务是对这4个操作数进行适当的算术运算,要求运算结果等于24。

    您可以使用的运算只有:+,-,*,/,您还可以使用()来改变运算顺序。注意:所有的中间结果须是整数,所以一些除法运算是不允许的(例如,(2*2)/4是合法的,2*(2/4)是不合法的)。下面我们给出一个游戏的具体例子:

    若给出的4个操作数是:1、2、3、7,则一种可能的解答是1+2+3*7=24。

    输入输出格式

    输入格式:

    只有一行,四个1到9之间的自然数。

    输出格式:

    如果有解的话,只要输出一个解,输出的是三行数据,分别表示运算的步骤。其中第一行是输入的两个数和一个运算符和运算后的结果,第二行是第一行的结果和一个输入的数据、运算符、运算后的结果,或者是另外两个数的输出结果;第三行是前面的结果第二行的结果或者剩下的一个数字、运算符和“=24”。如果两个操作数有大小的话则先输出大的。

    如果没有解则输出“No answer!”

    如果有多重合法解,输出任意一种即可。

    注:所有运算结果均为正整数

    输入输出样例

    输入样例#1:
    1 2 3 7
    
    输出样例#1:
    2+1=3
    7*3=21
    21+3=24
    

    说明

    感谢chenyy提供special judge

    分析:很显然,这是一道爆搜的题,关键就是看哪一种搜索的方式容易写,不会错.

          1.我们可以搜每个符号的位置,这样的话要判断是否合法,并且要在栈里面进行运算,超级麻烦.

          2.考虑能不能省去括号,其实是可以的,因为括号的作用无非就是改变运算顺序,我们只需要每次枚举哪两个数运算就好了.

          3.如果用上面那种方法,那么我们也不需要用栈处理了,因为所有的运算顺序都被枚举到了.

    接下来是输出的问题,只需要输出3个式子,在每次计算的时候记录一下第i次计算的数字和符号就好了。我本来想用第一种方法,题解中第二种方法很好,学习了.正所谓多一层枚举,少一点编程复杂度.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    
    using namespace std;
    
    int d[5][5],ans[5][3],fuhao[5];
    
    int jisuan(int x,int y,int op)
    {
        if (op == 1)
        return x + y;
        if (op == 2)
        return x - y;
        if (op == 3)
        return x * y;
        if (op == 4)
        return x / y;
    }
    
    char zhuanhuan(int k)
    {
        if (k == 1)
        return '+';
        if (k == 2)
        return '-';
        if (k == 3)
        return '*';
        if (k == 4)
        return '/';
    }
    
    void print()
    {
        for(int i = 4; i >= 2; i--)
            printf("%d%c%d=%d
    ",ans[i][1],zhuanhuan(fuhao[i]),ans[i][2],d[i - 1][1]);
        exit(0);
    }
    
    void dfs(int dep)
    {
        if (dep == 1)
        {
            if (d[1][1] == 24)
            print();
            return;
        }
        for (int i = 1; i <= dep; i++)
        for (int j = 1; j <= dep; j++)
        if (i != j)
        {
            for (int k = 1; k <= 4; k++)
            {
                /*
                1 --- +
                2 --- -
                3 --- *
                4 --- /
                */
                if ((k == 2 && d[dep][i] <= d[dep][j]) || (k == 4 && d[dep][j] != 0 && d[dep][i] % d[dep][j] != 0))
                continue;
                ans[dep][1] = max(d[dep][i],d[dep][j]);
                ans[dep][2] = min(d[dep][i],d[dep][j]);
                fuhao[dep] = k;
                int cnt = 0;
                d[dep - 1][++cnt] = jisuan(d[dep][i],d[dep][j],k);
                for (int l = 1; l <= dep; l++)
                if (l != i && l != j)
                d[dep - 1][++cnt] = d[dep][l];
                dfs(dep - 1);
            }
        }
    }
    
    int main()
    {
        for (int i = 1; i <= 4; i++)
        scanf("%d",&d[4][i]);
        dfs(4);
        printf("No answer!");
        
        return 0;
     } 
  • 相关阅读:
    第三方插件处理 json数据的易错点
    C# 生成缩略图 方法
    javascript 数组的数据删除 splice() 的问题
    System.InvalidOperationException: 未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序。
    C#单的二维码生成
    “System.NullReferenceException”类型的异常在 App_Web_j2s3gau3.dll 中发生,但未在用户代码中进行处理的Bug解决方案
    C#实现简单的邮件发送功能
    Python配置管理的几种方式
    Airflow 入门教程&示例
    pandas 使用 df.product 条件筛选报错Keyerror:False
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7473254.html
Copyright © 2020-2023  润新知