使用递归的C程序需要得到优化和修复

使用递归的C程序需要得到优化和修复,c,optimization,recursion,integer,long-long,C,Optimization,Recursion,Integer,Long Long,我正在解决一个任务,一个用户正在输入3个数字,a,b,c。目标是找出你是否能得到c求和a和b。在每个步骤中,允许将a添加到b,并将b添加到a。我需要找出输入的数字是否可能。输入的数字介于0和10^18之间。下面是我用递归完成的代码 解决a=4 b=6 c=38的任务示例: a=4 b=10 a=14b=10 a=14b=24 a=38 b=24打印是 我下面的代码在低数字的情况下做得很好,但我认为我正在输掉与大数字的战斗。。。我对该部分正在做什么添加了一些评论 我需要帮助的是,我需要它更好、更快

我正在解决一个任务,一个用户正在输入3个数字,
a,b,c
。目标是找出你是否能得到
c
求和
a
b
。在每个步骤中,允许将
a
添加到
b
,并将
b
添加到
a
。我需要找出输入的数字是否可能。输入的数字介于
0
10^18
之间。下面是我用递归完成的代码

解决
a=4 b=6 c=38的任务示例:

  • a=4 b=10
  • a=14b=10
  • a=14b=24
  • a=38 b=24打印是
  • 我下面的代码在低数字的情况下做得很好,但我认为我正在输掉与大数字的战斗。。。我对该部分正在做什么添加了一些评论


    我需要帮助的是,我需要它更好、更快地工作,我不知道如何更好地优化它

    //the function that I'm using
    int task(long long int a, long long int b, long long int c, long long int d, int p) 
    { //a, b and c are long long integers that are submited by the user, d is the sum of
      //the unchanged a and b, and p is a flag
        if(!a && !b && c) return 0; //0+0 will never get to 1
        if(c==d) return 1; //if I get with c to d, it is confirmed yes, 
                           //did the math with a pen :)
        if(c<d || c<=0) // I thought this is a nice case to stop
        {
            return 0;
        }
        if(p==1)
        {
            if(a>c) return 0; //if the flag p is one, that means i changed a, 
                              //so compare a
        }
        if(p==2)
        {
            if(b>c) return 0; //if p is two, i changed b so compare b
        }
        if(c-d>0) return task(a+b, b, c-b, d, 1)||task(a, b+a, c-a, d, 2);  
                //recursion call with OR operator so every step is checked
    
    }//one part is a=a+b b=b c=c-b, i decrement c so fewer steps are needed, 
     //the other part is when i add a to b
    
    int main()
    {
        long long int a,b,c;
        scanf("%I64d%I64d%I64d",&a,&b,&c); //scaning
        int p; //the flag for the first numbers
        if(a>b) p=1; //i dont know if i need this step at all xD
        else p=2; //but to make sure
        if((a==1 || b==1) && c) printf("YES"); //a=1 b=1 and c>=1 means i can get to c,
                                               //even with a+b+b+b..
        else if(a==c || b==c) printf("YES"); //if one of the numbers are already same 
                                             //with c, no need to check
        else if(task(a,b,c,a+b,p)) printf("YES"); //if the function returns 1, print YES
        else printf("NO"); //or print NO
    
    
        return 0;
    }
    
    //我正在使用的函数
    整型任务(长整型a、长整型b、长整型c、长整型d、长整型p)
    {//a、b和c是用户提交的长整数,d是
    //a和b不变,p是一个标志
    如果(!a&&!b&&c)返回0;//0+0将永远不会到达1
    如果(c==d)返回1;//如果使用c到d,则确认为是,
    //用钢笔做数学题:)
    if(cc)返回0;//如果p是2,我更改了b,所以比较b
    }
    如果(c-d>0)返回任务(a+b,b,c-b,d,1)|返回任务(a,b+a,c-a,d,2);
    //使用OR运算符调用递归,以便检查每个步骤
    }//一部分是a=a+b=b c=c-b,i减小c,因此需要更少的步骤,
    //另一部分是当我将a添加到b时
    int main()
    {
    长整型a、b、c;
    scanf(“%I64d%I64d%I64d”、&a、&b和&c);//扫描
    int p;//第一个数字的标志
    如果(a>b)p=1;//我根本不知道我是否需要这个步骤xD
    else p=2;//但要确保
    如果((a==1 | | b==1)和&c)printf(“是”)//a=1b=1和c>=1意味着我可以到达c,
    //即使是a+b+b+b。。
    else if(a==c | | b==c)printf(“YES”);//如果其中一个数字已经相同
    //使用c,无需检查
    else if(task(a,b,c,a+b,p))printf(“YES”);//如果函数返回1,则打印YES
    else printf(“NO”);//或print NO
    返回0;
    }
    
    也许我没有正确理解这个问题,但这里有两种不同的迭代方法。也许这可以帮助你:

    #include <stdio.h>
    
    int old_task( long a, long b, long c )
    {
       size_t iteration;
       long left = a, right = b;
       for( iteration = 0; ( left < c ) && ( right < c ); ++iteration )
       {
          printf( "NOT %ld: %ld, %ld < %ld\n", iteration, left, right, c );
          if( iteration % 2 )
             left += right;
          else
             right += left;
       }
       printf( "STOP %ld: %ld, %ld < %ld\n", iteration, left, right, c );
       return ( ( left == c ) || ( right == c ) ) ? 1 : 0;
    }
    
    int task( long a, long b, long c )
    {
        long f;
        /*long i = 0;*/
        for( f = a; f < c; f+= a )
        {
            /*printf( "Checking: %li * %li + %li * %li == %li\n", a, ++i, b, ( c - f ) / b, c );*/
            if( ( c - f ) % b == 0 )
                return 1;
        }
        return 0;
    }
    
    int main()
    {
       long a,b,c;
       scanf("%ld %ld %ld",&a,&b,&c); //scaning
    
       printf( "%s\n\n", task( a, b, c ) ? "YES" : "NO" );
       return 0;
    }
    
    #包括
    int old_任务(长a、长b、长c)
    {
    规模迭代;
    左长=a,右长=b;
    对于(迭代=0;(左
    我认为这可以用线性代数来解决。 假设a=3,b=4,c=15。所以你要找的是

    3x + 4y = 15
    x = (15-4y) / 3
    
    所以如果你把它除以3,它应该没有余数。我想线性代数来了,因为 15-4y应为0模3

    这只是一个想法

    我下面的代码对于低数字很有效

    没有。尝试输入
    23
    。最明显的错误是:

    In function 'main': warning: format '%I64d' expects type 'int *', but argument 2 has type 'long long int *' warning: format '%I64d' expects type 'int *', but argument 3 has type 'long long int *' warning: format '%I64d' expects type 'int *', but argument 4 has type 'long long int *' 在函数“main”中: 警告:格式“%I64d”要求类型为“int*”,但参数2的类型为“long-long-int*” 警告:格式“%I64d”要求类型为“int*”,但参数3的类型为“long-long-int*” 警告:格式“%I64d”要求类型为“int*”,但参数4的类型为“long-long-int*” 要更正它,请将
    %I64d
    替换为
    %Ld

    但我认为我正在输掉与更大数字的战斗


    当然,递归解决方案会使堆栈溢出;对于需要较少堆栈空间的程序,请参阅。

    我将更关注改进算法。我觉得很可能有一些数论原理,你可以用它来把它变成一个迭代,而不是递归。它也可能只是需要动态规划,我希望我自己能更好地理解它。@Galvanic是用a和b的倍数来找到c,还是c是否在a、b、a+b、a+a+b、a+a+b、a+a+a+b+b等序列的提升中?@George Houpis,不是n x a+m x b,最近有人问这个问题,称为树递归,但我还找不到。前一个问题的问题不是如何解决它,“但是如何防止它耗尽堆栈空间呢?”上一个问题:我认为这可能会返回错误的肯定答案。但是你不否认它也会给出正确的答案吗?不,我不否认。但只要总是说真话,就会得到正确的答案。我认为一个完整的答案只有在实际答案为真时才是真的。我明白你的意思,但正如我提到的,“这只是一个想法”。如果它在应该做的时候给出true,在应该做的时候给出true,并且只在几次内给出false,那么检查它是否是好的是非常简单和便宜的(被称为递归)。为什么是-1?请解释。我在上面的评论中解释过。“我需要帮助的是,我需要它更好、更快地工作,我不知道如何更好地优化它。”如果非常明确地询问如何优化。我不认为这会导致投票被否决……据我所知,他们是一样的,甚至是10^18的限制,同样的h