P1236 算24点

细节爆搜是真的牛逼。。。

题目意思非常的简单:给你4个数,可以任意添加运算符和括号,判断运算结果可不可能出现24?若可能输出方案的任意一种。(spj真好)

如果考虑上那些括号的话会很麻烦,于是我就翻题解发现可以使用后缀表达式来解决。

我的做法是构造一个字符串来表示一个后缀表达式,填运算符的话可以用dfs解决,注意细节就能调出来。

得到后缀表达式我们就可以求解了,如果求解的答案是24的话直接再算一次,输出我进行的那三次运算,然后exit就可以了。

整体来说就是这么简单。。。


下面是细节(毒瘤)部分

  1. 注意:所有的中间结果须是整数,所以一些除法运算是不允许的。

所以我们在运算的时候,当中间结果不整除的话就不行了。

  1. 如果两个操作数有大小的话则先输出大的。

所以在输出方案的时候碰到加法或者乘法这种满足交换律的,维护一下就ok了。

如果不这么写的话你怕是连样例都过不去。

  1. 注意0不能被除。(参考题解)

所以特判一下就可以了。我没有特判结果好多个RE。

  1. 运算中不能出现0和负数(特判解决)。(参考题解)

继续特判,加上这个我就能A了。

代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<stack>
const char pp[] = {'+', '-', '*', '/'};
int a[50];

char ch[350];
int p[50];

void print()
{
    for(int i = 1; i <= p[4]; i++)
    {
        printf("%c", ch[i]);
    }
    printf("\n");
}
int cal(bool printit)
{
    //print();
    std::stack<int> sta;
    for(int i = 1; i <= p[4]; i++)
    {
        if(ch[i] == 0) continue;
        if(ch[i] >= '0' && ch[i] <= '9') sta.push(ch[i] - '0');
        else
        {
            char sym = ch[i];
            int y = sta.top(); sta.pop();
            int x = sta.top(); sta.pop();
            if(sym == '/')
            {
                if(y == 0) return -1;
                if(x / y * y != x) return -1;
                sta.push(x / y);
            }
            else if(sym == '+')
            {
                if(x < y) std::swap(x, y);
                sta.push(x + y);
            }
            else if(sym == '-') sta.push(x - y);
            else if(sym == '*')
            {
                if(x < y) std::swap(x, y);
                sta.push(x * y);
            }
            if(sta.top() <= 0) return -1;
            if(printit) printf("%d%c%d=%d\n", x, sym, y, sta.top());
        }
    }
    return sta.top();
}
void dfs(int t, int pre)
{
    if(t == 5)
    {
        //print();
        if(pre != 3) return;
        if(cal(false) == 24)
        {
            cal(true);
            exit(0);
        }
        return;
    }
    if(t - pre > 1)
    {
        for(int i = 0; i < 4; i++)
        {
            ch[++p[t]] = pp[i];
            dfs(t, pre + 1);
            ch[p[t]--] = 0;
        }
    }
    dfs(t + 1, pre);
}
int main()
{
    scanf("%d%d%d%d", &a[1], &a[2], &a[3], &a[4]);
    do
    {
        //memset(ch, 0, sizeof ch);
        ch[1] = a[1] + '0';
        ch[6] = a[2] + '0';
        ch[11] = a[3] + '0';
        ch[16] = a[4] + '0';
        p[1] = 1; p[2] = 6;
        p[3] = 11; p[4] = 16;
        //print();
        dfs(2, 0);
    }
    while(std::next_permutation(a + 1, a + 5));
    printf("No answer!\n");
    return 0;
}
posted @ 2018-10-23 14:06  Garen-Wang  阅读(453)  评论(0编辑  收藏  举报