蓝桥杯24点算法,我感觉没问题但好像栈溢出,请帮我改一下


#include
using namespace std;
int n,sum,arr;
bool vis[20];
int a[20];
void dfs(int x, int y, int maxx,int z)
{
    
    if (maxx <= 24 && x <= y)
    {
        maxx = max(maxx, sum);
         arr=maxx;
    }
    for (int i = x; i <= y; i++)
    {
        vis[i] = 1;
        for (int j = z; j <= y; j++)
        {
            if (!vis[j])
            {
                for (int m = 1; m <= 4; m++)
                {
                    if (m == 1) sum =   a[j] * sum;
                    if(m==2) sum = sum + a[j];
                    if(m==3) sum = sum - a[j];
                    if(!a[j] && sum % a[j] == 0 && m == 4) sum = sum / a[j];
                    dfs(x, y, sum,z);
                }
            }
        }
        vis[i] = 0;
    }
}
int main()
{
    cin >> n;
    for (int i = 1; i <= 4 * n; i++)
    {
        cin >> a[i];
    }
    for (int i = 1; i <= n; i++)
    {
        sum = a[4 * i - 3];
        dfs(4*i - 3,  4 * i, 0,4*i-3);
        cout << arr<return 0;
}

“Devil组”引证GPT后的撰写:
你的程序中有两个问题:

  • 1.变量的作用域问题:你在dfs函数中定义了局部变量maxx和arr,但每次递归调用dfs时,这些变量并没有被重置为初始值。因此,在每次调用dfs时,这些变量的值都是上一次调用dfs时的值,导致程序出现错误。为了解决这个问题,你需要将maxx和arr定义为全局变量,或者将它们作为参数传递给dfs函数。
  • 2.循环嵌套问题:你的dfs函数中有三层循环嵌套,分别是i、j、m的循环。因为这些循环都是从x到y遍历,所以循环次数可能非常大,导致栈溢出。为了解决这个问题,你可以使用回溯法,即每次递归调用dfs时,只进行一次运算,然后回溯到上一层递归,再进行下一次运算。

修改后的代码

#include <iostream>
#include <cstring>
using namespace std;

const int N = 20;
int n;
int a[N];
bool st[N];

bool dfs(int depth, int res)
{
    if (depth == n)
    {
        return res == 24;
    }

    for (int i = 0; i < n; i++)
    {
        if (!st[i])
        {
            st[i] = true;
            if (dfs(depth + 1, res + a[i])) return true;
            if (dfs(depth + 1, res - a[i])) return true;
            if (dfs(depth + 1, res * a[i])) return true;
            if (a[i] && res % a[i] == 0 && dfs(depth + 1, res / a[i])) return true;
            st[i] = false;
        }
    }

    return false;
}

int main()
{
    while (cin >> a[0] >> a[1] >> a[2] >> a[3])
    {
        bool flag = false;
        memset(st, 0, sizeof st);
        for (int i = 0; i < 4; i++)
        {
            st[i] = true;
            if (dfs(1, a[i]))
            {
                flag = true;
                break;
            }
            st[i] = false;
        }
        if (flag) puts("Yes");
        else puts("No");
    }

    return 0;
}