C 欧拉计划#14
我目前正在解决: 下面的迭代序列是为一组正函数定义的 整数:C 欧拉计划#14,c,C,我目前正在解决: 下面的迭代序列是为一组正函数定义的 整数: n → n/2 (n is even) n → 3n + 1 (n is odd) Using the rule above and starting with 13, we generate the following sequence: 13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1 Which starting number, under one m
n → n/2 (n is even)
n → 3n + 1 (n is odd)
Using the rule above and starting with 13, we generate the following sequence:
13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
Which starting number, under one million, produces the longest chain?
我设计了以下算法来解决这个问题:
- 我尝试从1开始向后发展序列,而不是为每个数字分别寻找序列,这将包含大量冗余计算。也就是说,从数字开始,预测前面的元素李>
- 由于可以生成多个系列,请使用链接列表存储所有系列的最近编号。(这样做的目的是只存储序列较长的元素。)
- 我将循环这个,直到找到给定限制下的所有数字;限制下的最后一个数字将具有最长的序列李>
void series_generate(long num)
{
long n = 1;
addhead(n); //add 1 to list.
while (n < num)
{
series *p;
for (p = head; p != NULL; p = p->next)
{
long bf = p->num - 1;
if (p->num%2 == 0 && bf != 0 && bf%3 == 0) {
bf /= 3;
if (bf != 1)
addhead(bf);
if (bf < num)
n++;
}
p->num *= 2;
if ( p->num < num)
n++;
}
}
}
void系列\u生成(长数值)
{
长n=1;
addhead(n);//将1添加到列表中。
while(nnext)
{
长bf=p->num-1;
如果(p->num%2==0&&bf!=0&&bf%3==0){
bf/=3;
如果(bf!=1)
艾德海德(bf);
如果(bfnum*=2;
如果(p->num
然而,我没有得到我期望的答案。
有人能解释一下为什么这个算法不起作用吗?您正试图反向构建Collatz树,每层一层。因此,在内部循环的第次迭代之后,列表包含(在没有发生溢出的情况下)所有需要精确的
k
步数才能在其Collatz序列中达到1的数字
这种做法有两个严重问题
k
中的最大成员为2k。根据num
成员所使用的类型,在级别31、32、63或64时会出现溢出。然后,如果您使用有符号类型,那么您就有未定义的行为,列表中可能有负数,并且一切都会失控。如果使用无符号类型,则列表中包含一个0,所有这些都会出错由于27需要111个步骤才能达到1,因此每当
num>27时就会出现溢出,因此会得到错误的结果。您的算法返回的结果是什么,与您的期望有什么不同?您应该使用调试器逐行检查您的程序,为了找到第一条行为与你的意图不同的线,我用蛮力计算了这个问题的答案。我希望是837799BTW:这是Collatz循环//系列。@nhahtdh:链中最大的值几乎是570亿,需要36位。此问题需要64位整数类型。在讨论此序列中的步骤时,忽略1
作为其中一个步骤(即不计算)是否常见?直到今天我才听说过这个序列,现在我对“步骤”有点好奇,我指的是转换,n->n/2
resp<代码>n->3*n+1
。因此,我避免了是否包含1的问题。当谈到链条长度时,我不认为有一个明确的惯例,不管是数字[3,10,5,16,8,4,2,1]
(长度8)还是转换(7)才算。该序列也称为冰雹序列。