UVA problem 100 - The 3n + 1 problem
我已经尝试过所有测试用例,没有发现任何问题。 我检查的测试用例:
但为什么我一直都会错误回答?
这是我的代码:
#include "stdio.h"
unsigned long int cycle = 0, final = 0;
unsigned long int calculate(unsigned long int n)
{
if (n == 1)
{
return cycle + 1;
}
else
{
if (n % 2 == 0)
{
n = n / 2;
cycle = cycle + 1;
calculate(n);
}
else
{
n = 3 * n;
n = n + 1;
cycle = cycle+1;
calculate(n);
}
}
}
int main()
{
unsigned long int i = 0, j = 0, loop = 0;
while(scanf("%ld %ld", &i, &j) != EOF)
{
if (i > j)
{
unsigned long int t = i;
i = j;
j = t;
}
for (loop = i; loop <= j; loop++)
{
cycle = 0;
cycle = calculate(loop);
if(cycle > final)
{
final = cycle;
}
}
printf("%ld %ld %ld\n", i, j, final);
final = 0;
}
return 0;
}
答案 0 :(得分:5)
线索是你收到 i , j 但是它没有说i&lt; j适用于所有情况,请在代码中检查该条件并记住始终按顺序打印:
<i>[space]<j>[space]<count>
答案 1 :(得分:2)
如果输入“乱序”,您可以交换数字,即使在输出中,当明确说明您应该保留输入顺序时。
答案 2 :(得分:1)
看不出你的测试用例是如何实际工作的;你的递归案例永远不会返回任何内容。
答案 3 :(得分:0)
这是冰雹序列,对吗?你试图从给定的N开始确定冰雹序列的长度。你知道,你真的应该拿出那个丑陋的全局变量。递归计算它是微不足道的:
long int hailstone_sequence_length(long int n)
{
if (n == 1) {
return 1;
} else if (n % 2 == 0) {
return hailstone_sequence_length(n / 2) + 1;
} else {
return hailstone_sequence_length(3*n + 1) + 1;
}
}
注意循环变量是如何消失的。这是不必要的,因为每次调用只需要为递归调用计算的值加1。递归最低点为1,因此我们将其计为1.所有其他递归步骤都加1,所以最后我们留下序列长度。
注意:此方法需要与输入n
成比例的堆栈深度。
我放弃使用unsigned,因为这对于做大多数数学来说是不合适的类型。从(无符号长整数)0中减去1时,会得到一个大于2的幂的正数。在大多数情况下,这不是一种理智的行为(但在少数情况下恰好是正确的行为)。
现在让我们讨论你哪里出错了。您的原始代码会尝试通过修改名为cycle
的全局计数器来测量hailstone序列长度。但是,main
函数需要calculate
返回一个值:您有cycle = calculate(...)
。
问题是你的两个案子没有返回任何东西!从未返回任何内容的函数中提取返回值是未定义的行为。
(n == 1)
案例确实返回了一些内容,但它也有一个错误:它无法增加cycle
;它只返回cycle + 1
,使循环保留原始值。
int main()
{
unsigned long int i=0,j=0,loop=0;
将这些更改为long。顺便说一下,scanf中的%ld
期望长,而不是无符号长。
while (scanf("%ld %ld",&i,&j) != EOF)
小心scanf:它的返回值多于EOF
。如果无法进行转换,Scanf将返回EOF。如果它能够扫描一个数字而不是第二个数字,它将返回1.基本上,这里更好的测试是!= 2
。如果scanf
没有返回2,则输入出错。
{
if(i > j)
{
unsigned long int t=i;i=j;j=t;
}
for(loop=i;loop<=j;loop++)
{
cycle=0;
cycle=calculate(loop );
if(cycle>final)
{
final=cycle;
}
}
计算现在称为hailstone_sequence_length
,因此该块可以只有一个局部变量:{ long len = hailstone_sequence_length(loop); if (len > final) final = len; }
也许final
应该被称为max_length
?
printf("%ld %ld %ld\n",i,j,final);
final=0;
final
应该是此循环中的局部变量,因为它分别用于每个测试用例。然后你不必记得把它设置为0。
}
return 0;
}
答案 4 :(得分:0)
这是一个仅供参考的单行班次
int three_n_plus_1(int n)
{
return n == 1 ? 1 : three_n_plus_1((n % 2 == 0) ? (n/2) : (3*n+1))+1;
}
不太确定你的代码如何在你计算它之后立即“循环”,因为'calculate'对于它的许多情况没有明确的返回值(你应该有编译器警告这个效果)。如果你没有循环=循环=计算(那么它可能会起作用吗?
并将它们捆绑在一起: -
int three_n_plus_1(int n)
{
return n == 1 ? 1 : three_n_plus_1((n % 2 == 0) ? (n/2) : (3*n+1))+1;
}
int max_int(int a, int b) { return (a > b) ? a : b; }
int min_int(int a, int b) { return (a < b) ? a : b; }
int main(int argc, char* argv[])
{
int i,j;
while(scanf("%d %d",&i, &j) == 2)
{
int value, largest_cycle = 0, last = max_int(i,j);
for(value = min_int(i,j); value <= last; value++) largest_cycle = max_int(largest_cycle, three_n_plus_1(value));
printf("%d %d %d\r\n",i, j, largest_cycle);
}
}