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;}