C 3n+;1在线法官程序
我已经写了一个程序来解决在线判断中的3n+1问题()。我注意到了一些重要的问题,例如,第一个输入可能比第二个输入小,等等 但当我在网上判断时,我总是收到错误答案的通知。你能帮我看看哪里出错吗。谢谢 下面是我的节目。注意,我使用一个数组来存储遍历数的循环C 3n+;1在线法官程序,c,C,我已经写了一个程序来解决在线判断中的3n+1问题()。我注意到了一些重要的问题,例如,第一个输入可能比第二个输入小,等等 但当我在网上判断时,我总是收到错误答案的通知。你能帮我看看哪里出错吗。谢谢 下面是我的节目。注意,我使用一个数组来存储遍历数的循环 #include <stdio.h> #include <stdlib.h> #include <limits.h> int main(int argc, char const *argv[]) {
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main(int argc, char const *argv[])
{
int maxcyc = 0;
int curcyc;
int i, min, max;
unsigned long n;
int *cach = (int *)malloc(1000000 * sizeof(int));
if (cach == NULL)
{
printf("Memory Allocation Error\n");
}
for (i = 0; i < 1000000; ++i)
{
cach[i] = 0;
}
if (scanf("%d %d", &min, &max) == 2)
{
printf("%d %d ", min, max);
if (min > max)
{
min = min ^ max;
max = max ^ min;
min = min ^ max;
}
for (i = min; i < max + 1; ++i)
{
curcyc = 1;
n = i;
while (n != 1)
{
if (n < 1000000 && cach[n])
{
curcyc = curcyc + cach[n] - 1;
break;
}
curcyc++;
if (n & 0x0001)
{
if (n >= ULONG_MAX / 3)
{
printf("%d overflow at step %d\n", i, curcyc);
}
n = 3 * n + 1;
}
else
{
n = n >> 1;
}
}
cach[i] = curcyc;
maxcyc = maxcyc > curcyc ? maxcyc : curcyc;
}
printf("%d\n", maxcyc);
}
free(cach);
return 0;
}
#包括
#包括
#包括
int main(int argc,char const*argv[]
{
int-maxcyc=0;
int curcyc;
int i,最小值,最大值;
无符号长n;
int*cach=(int*)malloc(1000000*sizeof(int));
if(cach==NULL)
{
printf(“内存分配错误\n”);
}
对于(i=0;i<1000000;++i)
{
cach[i]=0;
}
如果(扫描频率(“%d%d”、&min和&max)==2)
{
printf(“%d%d”,最小值,最大值);
如果(最小值>最大值)
{
最小值=最小值^max;
最大值=最大值^min;
最小值=最小值^max;
}
对于(i=min;i=ULONG_MAX/3)
{
printf(“%d溢出在步骤%d\n”,i,curcyc);
}
n=3*n+1;
}
其他的
{
n=n>>1;
}
}
cach[i]=curcyc;
maxcyc=maxcyc>curcyc?maxcyc:curcyc;
}
printf(“%d\n”,maxcyc);
}
免费(cach);
返回0;
}
PS:有关此问题的详细说明和说明,请参阅
我已经更新了代码,将n的类型更改为
unsigned long
,并添加了if
语句以期望检查以3*n+1开头的溢出。但该程序仍存在错误,未通过判决。仍然需要帮助。谢谢。将curcyc从1改为0,并且不要从缓存值中减去。因此,您的算法是错误的
此外,根据起始值,在算法执行过程中,n可能会溢出。我有信心这会起作用。它产生的答案与我在评论中提到的暴力
bc
程序的答案相同,最高可达100万(至少在我修改bc
程序以计算链中的值数量而不是转换数量之后)。它的速度非常快,高达100万。它会随着缓存在1000万和1亿之间的效率降低而减慢
示例输出(使用-d生产编译的代码
):
$j=10;对于0中的i;do j=“$j$i”/collatz那么你能给出输入/输出应该是什么样子的例子吗?这是collatz序列,输入可能包括n
个测试,然后是n个数字,你必须运行序列。我想有趣的问题是输出应该是什么。我的猜测是这行curcyc=curcyc+cach[n]-1
是错误的,但由于我不知道它应该计算什么,所以很难说。@user2699298例如,如果我输入“I j”,程序在输出中输出“I j k”,其中k是I和j之间整数的最大周期长度。一个更详细的说明可以参考在我可以扣除一分,因为缺乏缩进。我不这样认为。您可以在中看到3n+1问题的示例。1的循环也已经计算过了。我认为n不应该溢出。我已将其设置为unsigned int。当我使用输入1999999运行时,程序可以正确返回199999525。您得到正确答案纯属侥幸;您的代码将生成一个范围为20-30的答案。这个答案非常隐晦地告诉你什么需要修复。您肯定会得到32位值的溢出(输入704511在242个步骤中上升到56991483520;输入837799在524个步骤中只上升到2974984576)。如果您确信输入2需要两个步骤,那么您可以使用525,但我认为您通常会说2需要一个步骤才能到达1。@JonathanLeffler非常感谢您。我发现当输入为704511和837799时,我的程序实际上会溢出。我已将n的类型更改为unsigned long。但我仍然收到错误答案的通知(可能在其他输入中溢出?我如何检查?)。我确信输入2需要两个步骤,因为在3n+1问题指令的例子中,它说22的周期长度是16。1处的步长也被计算在内。OK;他们想要序列中的值的数量,而不是达到1所需的操作计数。如果您在64位Unix系统上,则unsigned long
应该可以(对于超过1000000的距离)。如果您在32位计算机或Windows 64位计算机上,则需要转到64位类型;标准的是无符号long
。我有一个用bc
编写的程序来进行计算(速度不快,但准确)。计算100万的所有值需要三分钟半的时间,但不使用缓存来加速蛮力计算。感谢您的帮助。我得到了它。
$ j=10; for i in 0 0 0 0 0 0 0; do j="$j$i"; ./collatz-so <<< "2 $j"; done
2 100 119
2 1000 179
2 10000 262
2 100000 351
2 1000000 525
2 10000000 686
2 100000000 950
$
$ ./collatz-so <<< '1 30'
1: 1
2: 2
3: 8
4: 3
5: 6
6: 9
7: 17
8: 4
9: 20
10: 7
11: 15
12: 10
13: 10
14: 18
15: 18
16: 5
17: 13
18: 21
19: 21
20: 8
21: 8
22: 16
23: 16
24: 11
25: 24
26: 11
27: 112
28: 19
29: 19
30: 19
1 30 112
$
#include <stdio.h>
#include <stdlib.h>
#if defined(PRODUCTION)
#define DEBUG 0
#else
#define DEBUG 1
#endif
static const int debug = DEBUG;
enum { CACHE_SIZE = 1000000 };
int main(void)
{
int maxcyc = 0;
int curcyc;
int i, min, max;
unsigned long n;
int *cache = (int *)calloc(CACHE_SIZE, sizeof(int));
if (cache == NULL)
{
printf("Memory Allocation Error\n");
return 1;
}
if (scanf("%d %d", &min, &max) == 2)
{
if (min > max)
{
min = min ^ max;
max = max ^ min;
min = min ^ max;
}
for (i = min; i < max + 1; ++i)
{
curcyc = 1;
n = i;
while (n != 1)
{
if (n < CACHE_SIZE && cache[n])
{
//printf("%lu: cache[%lu] = %d; c = %d\n", n, n, cache[n], curcyc);
curcyc += cache[n] - 1;
break;
}
curcyc++;
if (n & 0x0001)
n = 3 * n + 1;
else
n /= 2;
}
if (i < CACHE_SIZE)
{
cache[i] = curcyc;
//printf("cache[%d] = %d\n", i, curcyc);
}
if (debug)
printf("%4d: %4d\n", i, curcyc);
maxcyc = maxcyc > curcyc ? maxcyc : curcyc;
}
printf("%d %d %d\n", min, max, maxcyc);
}
free(cache);
return 0;
}