24小时热门版块排行榜    

查看: 2317  |  回复: 9
本帖产生 4 个 程序强帖 ,点击这里进行查看

holmescn

金虫 (正式写手)

[交流] Euler 工程 第14题:找最长的数列 已有6人参与

周末了,放个题出来玩玩:

定义一个正整数数列,其迭代公式为:
n = n/2 (当n为偶数)
n = 3n+1 (当n为奇数)

比如从n=13开始,计算这个数列得:
13 ->40->20->10->5->16->8->4->1
这个数列一共有10项。
这个数列是不是总收敛到1还是个没有解决的问题(称为Collatz Problem)
不过,我们并不是要解这个难题,而是要求在小于1百万的所有起始数中,哪个数能产生最长的数列。

这里要注意的是,数列中间的项是可以大于1百万的,要看提最后数列终止到1时候的长度。

PS:这东西不能用归纳法证出来吗?
PS2:注意1分钟原则啊。不过,大于1分钟的程序也可以发上来,这样才有的交流。

Here we go!
回复此楼

» 猜你喜欢

» 本主题相关价值贴推荐,对您同样有帮助:

已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

huycwork

金虫 (著名写手)

★ ★ ★ ★
小木虫(金币+0.5):给个红包,谢谢回帖
余泽成(金币+3, 程序强帖+1): 辛苦了! 2011-05-20 21:02:20
昨天写好这个了,C++版本的是酱紫:
CODE:
#include
enum {BUFSZ = 1000000};

size_t eular14(size_t bufsz = 1000000){
        size_t buf[BUFSZ+1];
        size_t max = 1, c, r;
        long long n;
        buf[1] = 1;
        for(int i = 2; i < BUFSZ + 1; ++i){
                n = i;
                c ^= c;
                while(1){
                        if(n < BUFSZ && buf[n])
                                break;
                        ++c;
                        if(n % 2){
                                n = 3*n + 1;
                        }else
                                n = n/2;
                }
                buf[i] = buf[n] + c;
                if(buf[i] > max){
                        max = buf[i];
                        r = i;
                }
        }
        return r;
}

int main(void){
        std::cout< }

漩涡的中心有一块空地,空空的。
2楼2011-05-20 17:05:54
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

wangww2011

木虫 (著名写手)

★ ★
小木虫(金币+0.5):给个红包,谢谢回帖
余泽成(金币+1): 说到! 2011-05-20 21:02:42
微尘、梦想(程序强帖+1): 很好,欢迎常来! 2011-05-21 19:18:45
给个迭代算法吧,0.05s 先看结果:
CODE:
max=837799  count=525
elapsed time=0.050000 seconds.

代码为
CODE:
#include
#include
#include

#define TIMERSTART clock_t start_time,stop_time;double elapsed_time;start_time = clock();
#define TIMERSTOP stop_time = clock();elapsed_time=(double)(stop_time-start_time)/CLOCKS_PER_SEC;printf("elapsed time=%f seconds.\n",elapsed_time);

#define N 1000001
static int count[N];

int euler14(long long n){
  int result;

  if(n0){
    return count[n];
  }

  if(n%2) {
    n=3*n+1;
  }else {
    n=n/2;
  }
  result=euler14(n);

  if(n     count[n]=result;
  }

  return result+1;
}


int main(void){
  int i=0;
  int max_count,max;

  TIMERSTART;
  count[1]=1;
  
  max_count=0;
  for(i=N-1;i>1;i--){
    if(count[i]==0){
       count[i]=euler14(i);
    }
    if(count[i]>max_count){
      max_count=count[i];
      max=i;
    }
  }

  printf("max=%d  count=%d\n",max,max_count);

  TIMERSTOP;

  return 0;
}

[ Last edited by wangww2011 on 2011-5-21 at 14:14 ]
3楼2011-05-20 17:53:37
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

huycwork

金虫 (著名写手)

★ ★ ★ ★
小木虫(金币+0.5):给个红包,谢谢回帖
余泽成(金币+3): 鼓励交流! 2011-05-20 21:03:01
这个用归纳法证明是证明不出来的
前提条件可以选2->1
但是后面无法作出归纳假设:就算你假设an -> ak,归纳的下一步骤就是a(n+1)没法推导a(k+1),你看代码就知道了,你无法知道中间产生的链条有多长,实际原因是无法知道中间经过的元素有哪些,当然也就无法归纳证明。
漩涡的中心有一块空地,空空的。
4楼2011-05-20 18:03:01
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

微尘、梦想

木虫 (知名作家)

★ ★
小木虫(金币+0.5):给个红包,谢谢回帖
余泽成(金币+1): 鼓励交流! 2011-05-20 21:03:21
这不是著名的3x+1问题吗?以前写过这个程序,也试着证过这道题,看着挺简单,要真证起来,才发现根本不可能,否则它也不是世界难题了……
任风云变幻,我笑对人生!
5楼2011-05-20 18:27:20
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

libralibra

至尊木虫 (著名写手)

骠骑将军

★ ★ ★
小木虫(金币+0.5):给个红包,谢谢回帖
jjdg(金币+2): 辛苦了 2011-05-21 00:51:59
微尘、梦想(程序强帖+1): 2011-05-21 19:19:39
matlab的,13s多哦
CODE:
%% Which starting number, under one million, produces the longest chain?
%   n = n/2 (even); n = 3*n+1 (odd) till n==1
% like starting from 13, we generate the following sequence (contains 10 terms)
%  13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1

function result = euler14()
tic;
n = 0;
len = 0;
big = 0;
result = 0;
for i=1:1e6
    n = i;
    len = 0;
    while n~=1
        if mod(n,2)==0
            n = n/2;
        else
            n = n*3+1;
        end
        len = len+1;
    end
    len = len+1; % n==1
   
    if len>big
        big = len;
        result = i;
    end
end
toc;
end

结果
CODE:
% Elapsed time is 13.644453 seconds.
% ans =
%       837799

matlab/VB/python/c++/Java写程序请发QQ邮件:790404545@qq.com
6楼2011-05-20 21:23:11
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

holmescn

金虫 (正式写手)

微尘、梦想(程序强帖+1): 2011-05-21 19:19:52
matlab果然是不给力啊,Fortran版的只要0.75s
CODE:
Program euler14
    Implicit None
    Integer :: maxLen = 0, l
    Integer(8) :: n
    Integer :: start, maxStart
    Real :: t1, t2
    Call CPU_Time(t1)
   
    Do start = 2, 1000000
        n = start
        l = 0
        Do While (n .gt. 1)
            If(mod(n, 2) .eq. 0) Then
                n = n / 2
            Else
                n = 3*n + 1
            EndIf
            l = l + 1
        EndDo
        l = l + 1
        If(l .gt. maxLen) Then
            maxLen = l
            maxStart = start
        EndIf
    EndDo
    Call CPU_Time(t2)
    Print *, "Result:", maxStart, maxLen, t2-t1
End Program euler14

结果同libralibra同学。不过恐怖的是,中间项居然会大于40亿啊。32位整数都保存不了了。最后总共有525项。这东西用Mathematica的NestList展开会是什么样?

现在的计算机速度太快了,以至于我们都不想去找一个更好的解法了,不过,这东西的解空间应该还能减小,我看到2到3000以内都还是单调上涨的呢。
7楼2011-05-21 13:40:36
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

wmc_1979

金虫 (小有名气)


小木虫(金币+0.5):给个红包,谢谢回帖
我计算出是     837799
项数  524

[ Last edited by wmc_1979 on 2011-5-21 at 20:38 ]
8楼2011-05-21 20:04:41
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

holmescn

金虫 (正式写手)


余泽成(金币+1): 谢谢参与交流! 2011-05-22 11:53:05
引用回帖:
Originally posted by wmc_1979 at 2011-05-21 20:04:41:
我计算出是     837799
项数  524

[ Last edited by wmc_1979 on 2011-5-21 at 20:38 ]

当n=1的时候,就退出循环了,所以认为最后计数的时候没有数1
9楼2011-05-22 09:08:54
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

chyanog

金虫 (小有名气)


小木虫: 金币+0.5, 给个红包,谢谢回帖
Mathematica和中的递归可以很方便的“记忆化”,很简洁但还是没有编译后的循环快:
Euler 工程 第14题:找最长的数列
CODE:
c@1 = 1; c@n_ := c@n = 1 + If[EvenQ@n, c[n/2], c[3 n + 1]];
Ordering[c /@ Range@1*^6, -1] // AbsoluteTiming


cf = Compile[{{n0, _Integer}},
   Block[{n = N@n0},
    Catch@Do[If[n == 1, Throw@i];
      n = If[FractionalPart[n/2] == 0, n/2, 3*n + 1],
      {i, 1*^8}]
    ], RuntimeAttributes -> Listable,
   CompilationTarget -> "C", RuntimeOptions -> "Speed"
   ];

Ordering[cf@Range@1*^6, -1] // AbsoluteTiming

10楼2013-10-05 01:49:15
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 holmescn 的主题更新
普通表情 高级回复 (可上传附件)
信息提示
请填处理意见