使用递归的C程序需要得到优化和修复
我正在解决一个任务,一个用户正在输入3个数字,使用递归的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打印是 我下面的代码在低数字的情况下做得很好,但我认为我正在输掉与大数字的战斗。。。我对该部分正在做什么添加了一些评论 我需要帮助的是,我需要它更好、更快
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