zoukankan      html  css  js  c++  java
  • ProjectEuler 14

    求拉兹序列的最大链长:

    The following iterative sequence is defined for the set of positive integers:

    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

    It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.

    Which starting number, under one million, produces the longest chain?

    NOTE: Once the chain starts the terms are allowed to go above one million.

    思想:

    1、以空间来换取时间,使用一个map,每个key值对应每个数,每个value值对应该数拉兹序列的长度。

    2、如果一个数存在在map里,那么取出map的值即为结果

    3、如果一个数n不存在map里,取拉兹序列的下一个数tmp,(即n为偶数除以2,为奇数乘以3+1),那么map[n]=map[tmp]+1,取map跳步骤2

    通过这一个map可以减少许多不必要的计算,比如从1->5时计算:

    1,2通过初值设定map[1]=1,map[2]=2,不需要计算

    计算3时,map[3]=map[10]+1=8,map[10]=map[5]+1=7,map[5]=map[16]+1=6,map[16]=map[8]+1=5,map[8]=map[4]+1=4,map[4]=map[2]+1=3

    以上步骤是递归从后往前计算的,

    再计算4,map[4]再以上步骤已经计算过,那么不需要再计算,直接取map[4]=3

    同理计算5,有map[5]=6

     

    代码如下:

     1 private static int CollatzLen(long n, Map<Long, Integer> a) {
     2         if (n == 1)
     3             return a.get(1L);
     4         if (n == 2) {
     5             return a.get(2L);
     6         }
     7         if (a.get(n) != null)
     8             return a.get(n);
     9 
    10         long tmp = n / 2;
    11         if (n % 2 == 1)
    12             tmp = 6 * tmp + 4;
    13         if (a.get(n) == null)
    14             a.put(n, CollatzLen(tmp, a) + 1);
    15         else
    16             a.put(n, a.get(tmp) + 1);
    17         return a.get(n);
    18     }
    19 
    20     private static int longCollatz(int N) {
    21         int max = 0;
    22         int data = 1;
    23         Map<Long, Integer> a = new HashMap<Long, Integer>();
    24         a.put(1L, 1);
    25         a.put(2L, 2);
    26         for (int i = 1; i <= N; i++) {
    27             int tmp = CollatzLen(i, a);
    28             if (tmp > max) {
    29                 max = tmp;
    30                 data = i;
    31             }
    32         }
    33         // System.out.println("-------每个整数的Collatz链长-------");
    34         // for (long key : a.keySet()) {
    35         // System.out.print(key + " : " + a.get(key) + " , ");
    36         // }
    37         // System.out.println("-------每个整数的Collatz链长-------");
    38         return data;
    39     }
    View Code
  • 相关阅读:
    -webkit-user-select
    防火墙配置
    apache+tomcat集群部署笔记
    项目管理理念
    用plsql 导入导出oracle表结构数据
    Pair programming
    [整理]Linux压缩与解压缩命令整理。
    [转]虚拟机VMware3种网络模式(桥接、nat、Host-only)的工作原理
    [原创]VM虚拟机安装centos6.4详细图文教程
    [转]z-order引出的问题
  • 原文地址:https://www.cnblogs.com/lake19901126/p/3084485.html
Copyright © 2011-2022 走看看