[Luogu P1236] 算24点

嗯这是一道搜索好题啊。

搜索题,按照詹爷说的,就是尝试构造搜索树或者一张图。我们显然可以构造一棵森林,由于画工很差就不放出来了。

尝试把每个数作为第一个数开始搜索,然后枚举没有被选过的数,再枚举四则运算,搜索到当前值为24时打印算式。

但是这道题细节非常多,(我一开始没仔细看只得了10分qwq)。

  • 输出只有三行,也就是算式总数=3,大于或小于均不是合法解。
  • 两个操作数有大小先输出大的。
  • 无解输出"No answer!"
  • 所有运算结果均为正整数

这样才可以愉快的爆搜了。

其实中间运算结果可以大于24,之前我就剪错枝了。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#pragma GCC optimaze(2)
#pragma GCC optimaze(3)
using namespace std;

#define P system("pause");
#define B printf("Break\n");
#define A(x) cout << #x << " " << (x) << endl;
#define AA(x,y) cout << #x << " " << (x) << " " << #y << " " << (y) << endl;
#define ll long long
#define inf 1000000000
#define linf 10000000000000000

int read()
{
    int x = 0,f = 1;
    char c = getchar();
    while(c < '0' || c > '9')
    {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9')
    {
        x = (x << 3) + (x << 1) + c - '0';
        c = getchar();
    }
    return f * x;
}
struct cal
{
    int a,b,c;
    char op;
}ans[5];
int a[5],vis[5],flag,top;
void dfs(int now)
{
    if(now == 24 && top == 3 && !flag)
    {
        flag = 1;
        for(int i = 1;i <= top;i++)
        {
            cal p = ans[i];
            printf("%d%c%d=%d\n",p.a,p.op,p.b,p.c);
        }
        return;
    }
    if(top > 3 || now <= 0 || flag) return;
    for(int i = 1;i <= 4;i++)
    {
        if(vis[i]) continue;
        vis[i] = 1;

        ans[++top] = (cal){max(now,a[i]),min(now,a[i]),now + a[i],'+'};
        dfs(now + a[i]);
        top--;
        if(now > a[i])
        {
            ans[++top] = (cal){now,a[i],now - a[i],'-'};
            dfs(now - a[i]);
            top--;

            if(now % a[i] == 0)
            {
                ans[++top] = (cal){now,a[i],now / a[i],'/'};
                dfs(now / a[i]);
                top--;
            }
        }
        else
        {
            ans[++top] = (cal){a[i],now,a[i] - now,'-'};
            dfs(a[i] - now);
            top--;

            if(a[i] % now == 0)
            {
                ans[++top] = (cal){a[i],now,a[i] / now,'/'};
                dfs(a[i] / now);
                top--;
            }
        }

        ans[++top] = (cal){max(now,a[i]),min(now,a[i]),now * a[i],'*'};
        dfs(now * a[i]);
        top--;
        vis[i] = 0;
    }
}
int main()
{
    for(int i = 1;i <= 4;i++) a[i] = read();
    for(int i = 1;i <= 4 && !flag;i++)
    {
        vis[i] = 1;
        dfs(a[i]);
        vis[i] = 0;
    }
    if(!flag) puts("No answer!");
    return 0;
}

你可能感兴趣的:([Luogu P1236] 算24点)