zoukankan      html  css  js  c++  java
  • [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;
    }
  • 相关阅读:
    转:[Silverlight入门系列]使用MVVM模式(9): 想在ViewModel中控制TreeView节点展开?
    C#线程同步方法——Monitor
    转:Mongodb源码分析之Replication模式
    转:Mysql使用主从复制机制(replication)
    Ruby IDE
    转:ASP.NET MVC4细嚼慢咽---(5)js css文件合并
    转:ASP.NET MVC4细嚼慢咽---(6)全局过滤器
    转:WCF服务开发与调用的完整示例
    转:WF工作流技术内幕 —— 通过Web服务调用Workflow工作流(开发持久化工作流)
    汇总高效的卷积神经网络结构[转载]
  • 原文地址:https://www.cnblogs.com/taoxu0903/p/1987597.html
Copyright © 2011-2022 走看看