110101 The 3n+1 problem

来源:互联网 发布:java 正则表达式 括号 编辑:程序博客网 时间:2024/06/05 15:12


#include <stdlib.h>#include <malloc.h>#include <memory.h>#include <iostream>#include <vector>using namespace std;typedef unsigned int UINT;typedef unsigned short RESULT_t;#define LIMIT 1000001RESULT_t infos[LIMIT];void GetBoundaries(vector<UINT>& bounds1, vector<UINT>& bounds2){    UINT tmp1, tmp2;    while(cin >> tmp1 >> tmp2)    {        bounds1.push_back(tmp1);        bounds2.push_back(tmp2);    }}RESULT_t GetLen(UINT value){    if (value == 1)        return 1;    if ((value < LIMIT) && infos[value])        return infos[value];    RESULT_t len;    if ((value % 2) == 1)        len = GetLen(value * 3 + 1) + 1;    else        len = GetLen(value / 2) + 1;    if (value < LIMIT)        infos[value] = len;    return len;}#define Power2(x, n) ((x) << (n))void GetPartialMaxLenAndCleanForOdds(    UINT lower, UINT upper, UINT currentNumber,     RESULT_t currentLen, RESULT_t delta, RESULT_t& maxLen){    if ((currentNumber > upper) || (infos[currentNumber]))        return;    UINT j = (currentNumber << 1);    if ((j > upper) || (infos[j]))        return;    infos[currentNumber] = currentLen;    UINT middle = Power2(currentNumber, delta);    UINT midUpper = (upper > middle) ? middle : upper;    for(j = (currentNumber << 1); j <= midUpper; j <<= 1)    {        ++currentLen;        infos[j] = currentLen;    }    if (middle < upper)    {        for(j = (middle << 1); j <= upper; j <<= 1)        {            ++currentLen;            infos[j] = currentLen;            ++maxLen;        }    }}void GetPartialMaxLenAndClean(    UINT lower, UINT upper,     UINT currentNumber, RESULT_t& maxLen){    RESULT_t currentLen = GetLen(currentNumber);    RESULT_t tmpMaxLen = currentLen;    UINT i;    for(i = (currentNumber<<1); i <= upper; i <<= 1)    {        ++tmpMaxLen;        infos[i] = tmpMaxLen;    }    if (tmpMaxLen > maxLen)        maxLen = tmpMaxLen;    if ((currentNumber % 2) == 1)    {        GetPartialMaxLenAndCleanForOdds(lower, upper, 3*currentNumber + 1, currentLen - 1, maxLen - currentLen + 1, maxLen);    }    else    {        i = currentNumber >> 1;        if ((i % 2) == 1)            GetPartialMaxLenAndCleanForOdds(lower, upper, 3*i + 1, currentLen - 2, maxLen - currentLen + 2, maxLen);    }}RESULT_t SmartGetMaxLen(UINT lower, UINT upper){    RESULT_t maxLen = 1;    for(UINT i = lower; i <= upper; ++i)    {        if (infos[i])        {            if (infos[i] > maxLen)                maxLen = infos[i];            continue;        }        RESULT_t tmpMaxLen = 1;        GetPartialMaxLenAndClean(lower, upper, i, tmpMaxLen);        if (tmpMaxLen > maxLen)            maxLen = tmpMaxLen;    }    return maxLen;}void OutputResult(UINT lower, UINT upper, RESULT_t maxLen){    cout << lower << " " << upper << " " << maxLen << endl;}void DoJob(UINT bound1, UINT bound2){    UINT lower = (bound1 > bound2) ? bound2 : bound1;    UINT upper = bound1 + bound2 - lower;    RESULT_t maxLen = SmartGetMaxLen(lower, upper);    OutputResult(bound1, bound2, maxLen);}int main(int argc, char* argv[]){    infos[1] = 1;    vector<UINT> bounds1, bounds2;    GetBoundaries(bounds1, bounds2);    for(UINT i = 0; i < bounds1.size(); ++i)    {        DoJob(bounds1[i], bounds2[i]);    }    return 0;}


原创粉丝点击