• [Problem 14]欧拉


    几点:

    1. 在问题规模大的时候,一定要检查选择的数据类型是否够用,会不会overflow。这里的case就是一个很好的例子。我的算法几分钟就写好了,也蛮正确的,除了对于start num i及chain中的number n的数据类型选择了int,这就导致在n被3n+1反复搞大后,超出了int的范围,变成了负数,也就进入了导致算不出结果来的死循环里(因为永远也算不到1了)。所以,切记:问题规模大的时候,一定仔细考虑清楚数据类型的选择。

    2. unsigned int的数据参与大规模运算要比long long快3倍以上。这里指的是仅仅替换i和n的数据类型。

    3. 在看到更多规律的基础上,我加了个map来试图减少一些运算,结果:在题目要求的1million的问题规模下,配合unsigned int的正确类型,算不出;在调整到1000以验证算法正确性的实验中,还是发现:使用map后,由于要多做很多排序和查找的工作,虽然节省了一些直接的chain中number的计算,但最终时间统计显示还是比不用map要慢。所以,在你确定要使用map时,务必考虑清楚你增加的运算和减少的运算之间的关系,不见得能改善多少算法性能,而且还容易产生副作用。算法时间复杂度的本质在于:其需要执行的基本运算的次数的多少。

    4. oh,my!我终于意识到:位操作要比乘除运算高效的多!在算法中,用n&1替换n%2来判断奇数偶数,时间花费从3秒多减少到了1秒左右!这个例子,我印象很深刻,非常有意义的实验。感谢problem 14 answer thread里的兄弟的启发。

    下面附上代码:

    View Code
    #include <iostream>
    #include 
    <map>
    #include 
    <ctime>
    using namespace std;

    int _tmain(int argc, _TCHAR* argv[])
    {
        clock_t startT 
    = clock();
        
    int maxNum = 10// initialized with starting number 13's chain length.
        unsigned int theStartNum = 13;    
        unsigned 
    int n  = 0// Be exact to choose its data type.
        for(unsigned int i = 14; i < 1000000; i++)
        {
            n 
    = i;
            
    int tempNum = 0;
            
    while(true// to calculate tempNum.
            {            
                
    // if(n%2) // odd. Using this, whole algorithm cost >3s.
                if(n&1// using this, cost 1s or so.
                {
                    n 
    = 3*+ 1 ;
                }
                
    else // even.                
                {
                    
    if(n == 16// minor optimization.
                    {
                        tempNum 
    += 4;
                        
    break;
                    }
                    
    else
                        n 
    /= 2;
                }

                tempNum
    ++;
                
    if(n == 1)
                    
    break;            
            }

            
    if(maxNum < tempNum)
            {
                maxNum 
    = tempNum;
                theStartNum 
    = i;
            }
        }

        clock_t endT 
    = clock();
        
    double spentT = difftime(endT, startT);
        cout 
    << "theNum is: " << theStartNum << endl;
        cout 
    << "theChain: " << maxNum << endl;
        cout 
    << "spentT:" << spentT << endl;

        
    return 0;
    }
  • 相关阅读:
    【Quartz】常用方法的使用方式(三)
    【Quartz】实现接口封装化(二)
    【Quartz】定时器初步实验(一)
    数据库和ado连接语句的使用总结
    PMP 德尔菲技术
    java 事务解释。
    防盗链--解释
    java月利率计算(等额本息贷款)
    java 日志的数据脱敏
    MDC 输出线程信息帮助定位问题
  • 原文地址:https://www.cnblogs.com/taoxu0903/p/1987597.html
Copyright © 2020-2023  润新知