当前位置: 首页 > 知识库问答 >
问题:

大输入(递归函数)分段错误

安经纶
2023-03-14
    ll solve(ll a, ll b, ll i){
        //base case
        if (a == 0) return i;
        if (b > a) return i+1;

        //recursive case
        if (b == 1) {
            return solve(a,b+1,i+1);
        }
        ll n = solve(a, b+1, i+1);
        ll m = solve(a/b, b, i+1);
        return min(n,m);
    }

int main(){
int t;  
cin >> t;
while(t--){
ll a, b;
cin >> a >> b;
cout << solve(a, b, 0)<< endl;

基本上问题来自codeforces(1485A)。问题是,当我给一些大的输入,如50000000a和5b时,这会给我带来分段错误,而代码对较小的输入很好。请帮我解决。

共有1个答案

莘翰采
2023-03-14

使用递归是一个糟糕的选择。你需要做所有明显的算法优化。

关键的见解是,对于任何在增加b之前进行除法的路径,都有一个在增加b之前不进行除法的路径是一样好的或更好的。当你可以除以一个更大的数字时,为什么要除以一个更小的数字,如果你无论如何都要使用这些步骤来增加数字呢?

有了这种洞察力,并且去掉递归,解决这个问题就变得微不足道了:

#include <iostream>

unsigned long long divisions(unsigned long long a, unsigned long long b)
{
    // figure out how many divide operations we need
    int ops = 0;
    while (a > 0)
    {
        a/=b;
        ops++;
    }
    return ops;
}

unsigned long long ops(unsigned long long a, unsigned long long b)
{
    // figure out how many divides we need with the smallest possible b
    unsigned long long min_ops = (b == 1) ? (1 + divisions(a, b+1)) : divisions(a, b);

    // try every sensible larger b to see if it takes fewer operations
    for (unsigned long long num_inc = 1; num_inc <= min_ops; ++num_inc)
    {
        unsigned long long ops = num_inc + divisions (a, b + num_inc);
        if (ops < min_ops)
            min_ops = ops;
    }
    return min_ops;
}

int main(void)
{
    int t;
    std::cin >> t;
    while (t--)
    {
       unsigned long long a, b;
       std::cin >> a >> b;
       std::cout << ops(a, b) << std::endl;
    }
}
 类似资料:
  • 我不明白为什么我会得到这个最大深度错误。iam试图使用bst递归方法在数组中查找数字索引,下面是我的代码 任何人都可以告诉我代码块中发生了什么 错误块: PS C:\Users\admin\Desktop\DSA

  • 问题内容: 我使用以下代码解决了Euler项目的问题10,该代码通过强力工作: 这三个功能的工作方式如下: isPrime 检查数字是否为质数; primeList 返回一个列表,其中包含一组在一定范围内且限制为“ n”的素数,并且; sumPrimes 对列表中所有数字的值求和。(不需要最后一个功能,但是我喜欢它的清晰度,特别是对于像我这样的初学者。) 然后,我编写了一个新函数 primeLis

  • 使用以下代码: 为什么这个输出: 而不是我所期望的,那就是: 我讨厌递归。我讨厌递归。我讨厌递归。谢谢

  • 问题 你想在一个函数中调用相同的函数。 解决方案 使用一个命名函数: ping = -> console.log "Pinged" setTimeout ping, 1000 若为未命名函数,则使用 @arguments.callee@: delay = 1000 setTimeout((-> console.log "Pinged" setTimeout arg

  • 在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。 举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用函数fact(n)表示,可以看出: fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n 所以,fact(n)可以表示为n x fact(n-1),

  • 在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。 举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用函数fact(n)表示,可以看出: fact(n)=n!=1\times2\times3\times\cdot\cdot\cdot\times(n-1)\times n=(n-1)!\times n=fact(n-1)\times n